diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/rv770.c')
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 295 |
1 files changed, 250 insertions, 45 deletions
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 9490da700749..4de51891aa6d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -41,20 +41,60 @@ | |||
41 | 41 | ||
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 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev); | ||
45 | |||
46 | u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) | ||
47 | { | ||
48 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; | ||
49 | u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); | ||
50 | |||
51 | /* Lock the graphics update lock */ | ||
52 | tmp |= AVIVO_D1GRPH_UPDATE_LOCK; | ||
53 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
54 | |||
55 | /* update the scanout addresses */ | ||
56 | if (radeon_crtc->crtc_id) { | ||
57 | WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
58 | WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
59 | } else { | ||
60 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
61 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); | ||
62 | } | ||
63 | WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
64 | (u32)crtc_base); | ||
65 | WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, | ||
66 | (u32)crtc_base); | ||
67 | |||
68 | /* Wait for update_pending to go high. */ | ||
69 | while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); | ||
70 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); | ||
71 | |||
72 | /* Unlock the lock, so double-buffering can take place inside vblank */ | ||
73 | tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; | ||
74 | WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); | ||
75 | |||
76 | /* Return current update_pending status: */ | ||
77 | return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; | ||
78 | } | ||
44 | 79 | ||
45 | /* get temperature in millidegrees */ | 80 | /* get temperature in millidegrees */ |
46 | u32 rv770_get_temp(struct radeon_device *rdev) | 81 | int rv770_get_temp(struct radeon_device *rdev) |
47 | { | 82 | { |
48 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> | 83 | u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> |
49 | ASIC_T_SHIFT; | 84 | ASIC_T_SHIFT; |
50 | u32 actual_temp = 0; | 85 | int actual_temp; |
51 | 86 | ||
52 | if ((temp >> 9) & 1) | 87 | if (temp & 0x400) |
53 | actual_temp = 0; | 88 | actual_temp = -256; |
54 | else | 89 | else if (temp & 0x200) |
55 | actual_temp = (temp >> 1) & 0xff; | 90 | actual_temp = 255; |
56 | 91 | else if (temp & 0x100) { | |
57 | return actual_temp * 1000; | 92 | actual_temp = temp & 0x1ff; |
93 | actual_temp |= ~0x1ff; | ||
94 | } else | ||
95 | actual_temp = temp & 0xff; | ||
96 | |||
97 | return (actual_temp * 1000) / 2; | ||
58 | } | 98 | } |
59 | 99 | ||
60 | void rv770_pm_misc(struct radeon_device *rdev) | 100 | void rv770_pm_misc(struct radeon_device *rdev) |
@@ -65,8 +105,11 @@ void rv770_pm_misc(struct radeon_device *rdev) | |||
65 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 105 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
66 | 106 | ||
67 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 107 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
108 | /* 0xff01 is a flag rather then an actual voltage */ | ||
109 | if (voltage->voltage == 0xff01) | ||
110 | return; | ||
68 | if (voltage->voltage != rdev->pm.current_vddc) { | 111 | if (voltage->voltage != rdev->pm.current_vddc) { |
69 | radeon_atom_set_voltage(rdev, voltage->voltage); | 112 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
70 | rdev->pm.current_vddc = voltage->voltage; | 113 | rdev->pm.current_vddc = voltage->voltage; |
71 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | 114 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); |
72 | } | 115 | } |
@@ -267,8 +310,9 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
267 | */ | 310 | */ |
268 | void r700_cp_stop(struct radeon_device *rdev) | 311 | void r700_cp_stop(struct radeon_device *rdev) |
269 | { | 312 | { |
270 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 313 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
271 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); | 314 | WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT)); |
315 | WREG32(SCRATCH_UMSK, 0); | ||
272 | } | 316 | } |
273 | 317 | ||
274 | static int rv770_cp_load_microcode(struct radeon_device *rdev) | 318 | static int rv770_cp_load_microcode(struct radeon_device *rdev) |
@@ -280,7 +324,11 @@ static int rv770_cp_load_microcode(struct radeon_device *rdev) | |||
280 | return -EINVAL; | 324 | return -EINVAL; |
281 | 325 | ||
282 | r700_cp_stop(rdev); | 326 | r700_cp_stop(rdev); |
283 | WREG32(CP_RB_CNTL, RB_NO_UPDATE | (15 << 8) | (3 << 0)); | 327 | WREG32(CP_RB_CNTL, |
328 | #ifdef __BIG_ENDIAN | ||
329 | BUF_SWAP_32BIT | | ||
330 | #endif | ||
331 | RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); | ||
284 | 332 | ||
285 | /* Reset cp */ | 333 | /* Reset cp */ |
286 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); | 334 | WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP); |
@@ -488,6 +536,55 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, | |||
488 | return backend_map; | 536 | return backend_map; |
489 | } | 537 | } |
490 | 538 | ||
539 | static void rv770_program_channel_remap(struct radeon_device *rdev) | ||
540 | { | ||
541 | u32 tcp_chan_steer, mc_shared_chremap, tmp; | ||
542 | bool force_no_swizzle; | ||
543 | |||
544 | switch (rdev->family) { | ||
545 | case CHIP_RV770: | ||
546 | case CHIP_RV730: | ||
547 | force_no_swizzle = false; | ||
548 | break; | ||
549 | case CHIP_RV710: | ||
550 | case CHIP_RV740: | ||
551 | default: | ||
552 | force_no_swizzle = true; | ||
553 | break; | ||
554 | } | ||
555 | |||
556 | tmp = RREG32(MC_SHARED_CHMAP); | ||
557 | switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { | ||
558 | case 0: | ||
559 | case 1: | ||
560 | default: | ||
561 | /* default mapping */ | ||
562 | mc_shared_chremap = 0x00fac688; | ||
563 | break; | ||
564 | case 2: | ||
565 | case 3: | ||
566 | if (force_no_swizzle) | ||
567 | mc_shared_chremap = 0x00fac688; | ||
568 | else | ||
569 | mc_shared_chremap = 0x00bbc298; | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | if (rdev->family == CHIP_RV740) | ||
574 | tcp_chan_steer = 0x00ef2a60; | ||
575 | else | ||
576 | tcp_chan_steer = 0x00fac688; | ||
577 | |||
578 | /* RV770 CE has special chremap setup */ | ||
579 | if (rdev->pdev->device == 0x944e) { | ||
580 | tcp_chan_steer = 0x00b08b08; | ||
581 | mc_shared_chremap = 0x00b08b08; | ||
582 | } | ||
583 | |||
584 | WREG32(TCP_CHAN_STEER, tcp_chan_steer); | ||
585 | WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); | ||
586 | } | ||
587 | |||
491 | static void rv770_gpu_init(struct radeon_device *rdev) | 588 | static void rv770_gpu_init(struct radeon_device *rdev) |
492 | { | 589 | { |
493 | int i, j, num_qd_pipes; | 590 | int i, j, num_qd_pipes; |
@@ -643,10 +740,11 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
643 | else | 740 | else |
644 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | 741 | gb_tiling_config |= BANK_TILING((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
645 | rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); | 742 | rdev->config.rv770.tiling_nbanks = 4 << ((gb_tiling_config >> 4) & 0x3); |
646 | 743 | gb_tiling_config |= GROUP_SIZE((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT); | |
647 | gb_tiling_config |= GROUP_SIZE(0); | 744 | if ((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) |
648 | rdev->config.rv770.tiling_group_size = 256; | 745 | rdev->config.rv770.tiling_group_size = 512; |
649 | 746 | else | |
747 | rdev->config.rv770.tiling_group_size = 256; | ||
650 | if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { | 748 | if (((mc_arb_ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT) > 3) { |
651 | gb_tiling_config |= ROW_TILING(3); | 749 | gb_tiling_config |= ROW_TILING(3); |
652 | gb_tiling_config |= SAMPLE_SPLIT(3); | 750 | gb_tiling_config |= SAMPLE_SPLIT(3); |
@@ -686,6 +784,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
686 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 784 | WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
687 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); | 785 | WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); |
688 | 786 | ||
787 | rv770_program_channel_remap(rdev); | ||
788 | |||
689 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); | 789 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); |
690 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 790 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
691 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); | 791 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
@@ -912,9 +1012,9 @@ static int rv770_vram_scratch_init(struct radeon_device *rdev) | |||
912 | u64 gpu_addr; | 1012 | u64 gpu_addr; |
913 | 1013 | ||
914 | if (rdev->vram_scratch.robj == NULL) { | 1014 | if (rdev->vram_scratch.robj == NULL) { |
915 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, | 1015 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, |
916 | true, RADEON_GEM_DOMAIN_VRAM, | 1016 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, |
917 | &rdev->vram_scratch.robj); | 1017 | &rdev->vram_scratch.robj); |
918 | if (r) { | 1018 | if (r) { |
919 | return r; | 1019 | return r; |
920 | } | 1020 | } |
@@ -954,6 +1054,45 @@ static void rv770_vram_scratch_fini(struct radeon_device *rdev) | |||
954 | radeon_bo_unref(&rdev->vram_scratch.robj); | 1054 | radeon_bo_unref(&rdev->vram_scratch.robj); |
955 | } | 1055 | } |
956 | 1056 | ||
1057 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | ||
1058 | { | ||
1059 | u64 size_bf, size_af; | ||
1060 | |||
1061 | if (mc->mc_vram_size > 0xE0000000) { | ||
1062 | /* leave room for at least 512M GTT */ | ||
1063 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1064 | mc->real_vram_size = 0xE0000000; | ||
1065 | mc->mc_vram_size = 0xE0000000; | ||
1066 | } | ||
1067 | if (rdev->flags & RADEON_IS_AGP) { | ||
1068 | size_bf = mc->gtt_start; | ||
1069 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | ||
1070 | if (size_bf > size_af) { | ||
1071 | if (mc->mc_vram_size > size_bf) { | ||
1072 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1073 | mc->real_vram_size = size_bf; | ||
1074 | mc->mc_vram_size = size_bf; | ||
1075 | } | ||
1076 | mc->vram_start = mc->gtt_start - mc->mc_vram_size; | ||
1077 | } else { | ||
1078 | if (mc->mc_vram_size > size_af) { | ||
1079 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
1080 | mc->real_vram_size = size_af; | ||
1081 | mc->mc_vram_size = size_af; | ||
1082 | } | ||
1083 | mc->vram_start = mc->gtt_end; | ||
1084 | } | ||
1085 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | ||
1086 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | ||
1087 | mc->mc_vram_size >> 20, mc->vram_start, | ||
1088 | mc->vram_end, mc->real_vram_size >> 20); | ||
1089 | } else { | ||
1090 | radeon_vram_location(rdev, &rdev->mc, 0); | ||
1091 | rdev->mc.gtt_base_align = 0; | ||
1092 | radeon_gtt_location(rdev, mc); | ||
1093 | } | ||
1094 | } | ||
1095 | |||
957 | int rv770_mc_init(struct radeon_device *rdev) | 1096 | int rv770_mc_init(struct radeon_device *rdev) |
958 | { | 1097 | { |
959 | u32 tmp; | 1098 | u32 tmp; |
@@ -993,8 +1132,7 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
993 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 1132 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
994 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 1133 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
995 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | 1134 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
996 | rdev->mc.active_vram_size = rdev->mc.visible_vram_size; | 1135 | r700_vram_gtt_location(rdev, &rdev->mc); |
997 | r600_vram_gtt_location(rdev, &rdev->mc); | ||
998 | radeon_update_bandwidth_info(rdev); | 1136 | radeon_update_bandwidth_info(rdev); |
999 | 1137 | ||
1000 | return 0; | 1138 | return 0; |
@@ -1004,6 +1142,9 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1004 | { | 1142 | { |
1005 | int r; | 1143 | int r; |
1006 | 1144 | ||
1145 | /* enable pcie gen2 link */ | ||
1146 | rv770_pcie_gen2_enable(rdev); | ||
1147 | |||
1007 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 1148 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
1008 | r = r600_init_microcode(rdev); | 1149 | r = r600_init_microcode(rdev); |
1009 | if (r) { | 1150 | if (r) { |
@@ -1030,19 +1171,12 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1030 | rdev->asic->copy = NULL; | 1171 | rdev->asic->copy = NULL; |
1031 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 1172 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
1032 | } | 1173 | } |
1033 | /* pin copy shader into vram */ | 1174 | |
1034 | if (rdev->r600_blit.shader_obj) { | 1175 | /* allocate wb buffer */ |
1035 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | 1176 | r = radeon_wb_init(rdev); |
1036 | if (unlikely(r != 0)) | 1177 | if (r) |
1037 | return r; | 1178 | return r; |
1038 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | 1179 | |
1039 | &rdev->r600_blit.shader_gpu_addr); | ||
1040 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1041 | if (r) { | ||
1042 | DRM_ERROR("failed to pin blit object %d\n", r); | ||
1043 | return r; | ||
1044 | } | ||
1045 | } | ||
1046 | /* Enable IRQ */ | 1180 | /* Enable IRQ */ |
1047 | r = r600_irq_init(rdev); | 1181 | r = r600_irq_init(rdev); |
1048 | if (r) { | 1182 | if (r) { |
@@ -1061,8 +1195,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1061 | r = r600_cp_resume(rdev); | 1195 | r = r600_cp_resume(rdev); |
1062 | if (r) | 1196 | if (r) |
1063 | return r; | 1197 | return r; |
1064 | /* write back buffer are not vital so don't worry about failure */ | 1198 | |
1065 | r600_wb_enable(rdev); | ||
1066 | return 0; | 1199 | return 0; |
1067 | } | 1200 | } |
1068 | 1201 | ||
@@ -1085,7 +1218,7 @@ int rv770_resume(struct radeon_device *rdev) | |||
1085 | 1218 | ||
1086 | r = r600_ib_test(rdev); | 1219 | r = r600_ib_test(rdev); |
1087 | if (r) { | 1220 | if (r) { |
1088 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 1221 | DRM_ERROR("radeon: failed testing IB (%d).\n", r); |
1089 | return r; | 1222 | return r; |
1090 | } | 1223 | } |
1091 | 1224 | ||
@@ -1108,7 +1241,7 @@ int rv770_suspend(struct radeon_device *rdev) | |||
1108 | r700_cp_stop(rdev); | 1241 | r700_cp_stop(rdev); |
1109 | rdev->cp.ready = false; | 1242 | rdev->cp.ready = false; |
1110 | r600_irq_suspend(rdev); | 1243 | r600_irq_suspend(rdev); |
1111 | r600_wb_disable(rdev); | 1244 | radeon_wb_disable(rdev); |
1112 | rv770_pcie_gart_disable(rdev); | 1245 | rv770_pcie_gart_disable(rdev); |
1113 | /* unpin shaders bo */ | 1246 | /* unpin shaders bo */ |
1114 | if (rdev->r600_blit.shader_obj) { | 1247 | if (rdev->r600_blit.shader_obj) { |
@@ -1131,9 +1264,6 @@ int rv770_init(struct radeon_device *rdev) | |||
1131 | { | 1264 | { |
1132 | int r; | 1265 | int r; |
1133 | 1266 | ||
1134 | r = radeon_dummy_page_init(rdev); | ||
1135 | if (r) | ||
1136 | return r; | ||
1137 | /* This don't do much */ | 1267 | /* This don't do much */ |
1138 | r = radeon_gem_init(rdev); | 1268 | r = radeon_gem_init(rdev); |
1139 | if (r) | 1269 | if (r) |
@@ -1152,7 +1282,7 @@ int rv770_init(struct radeon_device *rdev) | |||
1152 | if (r) | 1282 | if (r) |
1153 | return r; | 1283 | return r; |
1154 | /* Post card if necessary */ | 1284 | /* Post card if necessary */ |
1155 | if (!r600_card_posted(rdev)) { | 1285 | if (!radeon_card_posted(rdev)) { |
1156 | if (!rdev->bios) { | 1286 | if (!rdev->bios) { |
1157 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | 1287 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); |
1158 | return -EINVAL; | 1288 | return -EINVAL; |
@@ -1203,8 +1333,8 @@ int rv770_init(struct radeon_device *rdev) | |||
1203 | if (r) { | 1333 | if (r) { |
1204 | dev_err(rdev->dev, "disabling GPU acceleration\n"); | 1334 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
1205 | r700_cp_fini(rdev); | 1335 | r700_cp_fini(rdev); |
1206 | r600_wb_fini(rdev); | ||
1207 | r600_irq_fini(rdev); | 1336 | r600_irq_fini(rdev); |
1337 | radeon_wb_fini(rdev); | ||
1208 | radeon_irq_kms_fini(rdev); | 1338 | radeon_irq_kms_fini(rdev); |
1209 | rv770_pcie_gart_fini(rdev); | 1339 | rv770_pcie_gart_fini(rdev); |
1210 | rdev->accel_working = false; | 1340 | rdev->accel_working = false; |
@@ -1236,8 +1366,9 @@ void rv770_fini(struct radeon_device *rdev) | |||
1236 | { | 1366 | { |
1237 | r600_blit_fini(rdev); | 1367 | r600_blit_fini(rdev); |
1238 | r700_cp_fini(rdev); | 1368 | r700_cp_fini(rdev); |
1239 | r600_wb_fini(rdev); | ||
1240 | r600_irq_fini(rdev); | 1369 | r600_irq_fini(rdev); |
1370 | radeon_wb_fini(rdev); | ||
1371 | radeon_ib_pool_fini(rdev); | ||
1241 | radeon_irq_kms_fini(rdev); | 1372 | radeon_irq_kms_fini(rdev); |
1242 | rv770_pcie_gart_fini(rdev); | 1373 | rv770_pcie_gart_fini(rdev); |
1243 | rv770_vram_scratch_fini(rdev); | 1374 | rv770_vram_scratch_fini(rdev); |
@@ -1248,5 +1379,79 @@ void rv770_fini(struct radeon_device *rdev) | |||
1248 | radeon_atombios_fini(rdev); | 1379 | radeon_atombios_fini(rdev); |
1249 | kfree(rdev->bios); | 1380 | kfree(rdev->bios); |
1250 | rdev->bios = NULL; | 1381 | rdev->bios = NULL; |
1251 | radeon_dummy_page_fini(rdev); | 1382 | } |
1383 | |||
1384 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | ||
1385 | { | ||
1386 | u32 link_width_cntl, lanes, speed_cntl, tmp; | ||
1387 | u16 link_cntl2; | ||
1388 | |||
1389 | if (radeon_pcie_gen2 == 0) | ||
1390 | return; | ||
1391 | |||
1392 | if (rdev->flags & RADEON_IS_IGP) | ||
1393 | return; | ||
1394 | |||
1395 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
1396 | return; | ||
1397 | |||
1398 | /* x2 cards have a special sequence */ | ||
1399 | if (ASIC_IS_X2(rdev)) | ||
1400 | return; | ||
1401 | |||
1402 | /* advertise upconfig capability */ | ||
1403 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1404 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
1405 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1406 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1407 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
1408 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
1409 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
1410 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
1411 | link_width_cntl |= lanes | LC_RECONFIG_NOW | | ||
1412 | LC_RENEGOTIATE_EN | LC_UPCONFIGURE_SUPPORT; | ||
1413 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1414 | } else { | ||
1415 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
1416 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1417 | } | ||
1418 | |||
1419 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1420 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
1421 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
1422 | |||
1423 | tmp = RREG32(0x541c); | ||
1424 | WREG32(0x541c, tmp | 0x8); | ||
1425 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
1426 | link_cntl2 = RREG16(0x4088); | ||
1427 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
1428 | link_cntl2 |= 0x2; | ||
1429 | WREG16(0x4088, link_cntl2); | ||
1430 | WREG32(MM_CFGREGS_CNTL, 0); | ||
1431 | |||
1432 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1433 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
1434 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1435 | |||
1436 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1437 | speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
1438 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1439 | |||
1440 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1441 | speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; | ||
1442 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1443 | |||
1444 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
1445 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
1446 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
1447 | |||
1448 | } else { | ||
1449 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
1450 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
1451 | if (1) | ||
1452 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
1453 | else | ||
1454 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
1455 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
1456 | } | ||
1252 | } | 1457 | } |