diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2011-10-28 10:30:02 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-11-01 12:05:02 -0400 |
commit | 16cdf04d30c24a6e698863351c11d9a8da2591ed (patch) | |
tree | f104a8d49318daebd1e598d03eb1455e09288621 /drivers/gpu | |
parent | 996d5c59006cd970dd3a9007aa1f76532909bae2 (diff) |
drm/radeon/kms: allocate vram scratch page on 6xx+
The vram scratch was originally only used on some 7xx asics
to work around a hw bug. Allocate the scratch page on all 6xx+
radeons and set the MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR to point
to it. We shouldn't ever hit it since we limit the system
aperture to vram or vram and AGP, but better safe than sorry.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/rv770.c | 60 |
5 files changed, 80 insertions, 57 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index ed406e8404a3..db9027d871e3 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -3031,6 +3031,10 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
3031 | } | 3031 | } |
3032 | } | 3032 | } |
3033 | 3033 | ||
3034 | r = r600_vram_scratch_init(rdev); | ||
3035 | if (r) | ||
3036 | return r; | ||
3037 | |||
3034 | evergreen_mc_program(rdev); | 3038 | evergreen_mc_program(rdev); |
3035 | if (rdev->flags & RADEON_IS_AGP) { | 3039 | if (rdev->flags & RADEON_IS_AGP) { |
3036 | evergreen_agp_enable(rdev); | 3040 | evergreen_agp_enable(rdev); |
@@ -3235,6 +3239,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3235 | radeon_ib_pool_fini(rdev); | 3239 | radeon_ib_pool_fini(rdev); |
3236 | radeon_irq_kms_fini(rdev); | 3240 | radeon_irq_kms_fini(rdev); |
3237 | evergreen_pcie_gart_fini(rdev); | 3241 | evergreen_pcie_gart_fini(rdev); |
3242 | r600_vram_scratch_fini(rdev); | ||
3238 | radeon_gem_fini(rdev); | 3243 | radeon_gem_fini(rdev); |
3239 | radeon_fence_driver_fini(rdev); | 3244 | radeon_fence_driver_fini(rdev); |
3240 | radeon_agp_fini(rdev); | 3245 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 556b7bc3418b..56afaff6299a 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1361,6 +1361,10 @@ static int cayman_startup(struct radeon_device *rdev) | |||
1361 | return r; | 1361 | return r; |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | r = r600_vram_scratch_init(rdev); | ||
1365 | if (r) | ||
1366 | return r; | ||
1367 | |||
1364 | evergreen_mc_program(rdev); | 1368 | evergreen_mc_program(rdev); |
1365 | r = cayman_pcie_gart_enable(rdev); | 1369 | r = cayman_pcie_gart_enable(rdev); |
1366 | if (r) | 1370 | if (r) |
@@ -1556,6 +1560,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
1556 | radeon_ib_pool_fini(rdev); | 1560 | radeon_ib_pool_fini(rdev); |
1557 | radeon_irq_kms_fini(rdev); | 1561 | radeon_irq_kms_fini(rdev); |
1558 | cayman_pcie_gart_fini(rdev); | 1562 | cayman_pcie_gart_fini(rdev); |
1563 | r600_vram_scratch_fini(rdev); | ||
1559 | radeon_gem_fini(rdev); | 1564 | radeon_gem_fini(rdev); |
1560 | radeon_fence_driver_fini(rdev); | 1565 | radeon_fence_driver_fini(rdev); |
1561 | radeon_bo_fini(rdev); | 1566 | radeon_bo_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 1f007adc2723..75b8e004ca80 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1137,7 +1137,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
1137 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); | 1137 | WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); |
1138 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); | 1138 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12); |
1139 | } | 1139 | } |
1140 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 1140 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
1141 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 1141 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
1142 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 1142 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
1143 | WREG32(MC_VM_FB_LOCATION, tmp); | 1143 | WREG32(MC_VM_FB_LOCATION, tmp); |
@@ -1276,6 +1276,53 @@ int r600_mc_init(struct radeon_device *rdev) | |||
1276 | return 0; | 1276 | return 0; |
1277 | } | 1277 | } |
1278 | 1278 | ||
1279 | int r600_vram_scratch_init(struct radeon_device *rdev) | ||
1280 | { | ||
1281 | int r; | ||
1282 | |||
1283 | if (rdev->vram_scratch.robj == NULL) { | ||
1284 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
1285 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
1286 | &rdev->vram_scratch.robj); | ||
1287 | if (r) { | ||
1288 | return r; | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1292 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1293 | if (unlikely(r != 0)) | ||
1294 | return r; | ||
1295 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
1296 | RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr); | ||
1297 | if (r) { | ||
1298 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1299 | return r; | ||
1300 | } | ||
1301 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
1302 | (void **)&rdev->vram_scratch.ptr); | ||
1303 | if (r) | ||
1304 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1305 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1306 | |||
1307 | return r; | ||
1308 | } | ||
1309 | |||
1310 | void r600_vram_scratch_fini(struct radeon_device *rdev) | ||
1311 | { | ||
1312 | int r; | ||
1313 | |||
1314 | if (rdev->vram_scratch.robj == NULL) { | ||
1315 | return; | ||
1316 | } | ||
1317 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1318 | if (likely(r == 0)) { | ||
1319 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
1320 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1321 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1322 | } | ||
1323 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
1324 | } | ||
1325 | |||
1279 | /* We doesn't check that the GPU really needs a reset we simply do the | 1326 | /* We doesn't check that the GPU really needs a reset we simply do the |
1280 | * reset, it's up to the caller to determine if the GPU needs one. We | 1327 | * reset, it's up to the caller to determine if the GPU needs one. We |
1281 | * might add an helper function to check that. | 1328 | * might add an helper function to check that. |
@@ -2436,6 +2483,10 @@ int r600_startup(struct radeon_device *rdev) | |||
2436 | } | 2483 | } |
2437 | } | 2484 | } |
2438 | 2485 | ||
2486 | r = r600_vram_scratch_init(rdev); | ||
2487 | if (r) | ||
2488 | return r; | ||
2489 | |||
2439 | r600_mc_program(rdev); | 2490 | r600_mc_program(rdev); |
2440 | if (rdev->flags & RADEON_IS_AGP) { | 2491 | if (rdev->flags & RADEON_IS_AGP) { |
2441 | r600_agp_enable(rdev); | 2492 | r600_agp_enable(rdev); |
@@ -2656,6 +2707,7 @@ void r600_fini(struct radeon_device *rdev) | |||
2656 | radeon_ib_pool_fini(rdev); | 2707 | radeon_ib_pool_fini(rdev); |
2657 | radeon_irq_kms_fini(rdev); | 2708 | radeon_irq_kms_fini(rdev); |
2658 | r600_pcie_gart_fini(rdev); | 2709 | r600_pcie_gart_fini(rdev); |
2710 | r600_vram_scratch_fini(rdev); | ||
2659 | radeon_agp_fini(rdev); | 2711 | radeon_agp_fini(rdev); |
2660 | radeon_gem_fini(rdev); | 2712 | radeon_gem_fini(rdev); |
2661 | radeon_fence_driver_fini(rdev); | 2713 | radeon_fence_driver_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 00f6dc4973a9..83b76db7bcfd 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1144,10 +1144,11 @@ int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, | |||
1144 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, | 1144 | int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, |
1145 | struct drm_file *filp); | 1145 | struct drm_file *filp); |
1146 | 1146 | ||
1147 | /* VRAM scratch page for HDP bug */ | 1147 | /* VRAM scratch page for HDP bug, default vram page */ |
1148 | struct r700_vram_scratch { | 1148 | struct r600_vram_scratch { |
1149 | struct radeon_bo *robj; | 1149 | struct radeon_bo *robj; |
1150 | volatile uint32_t *ptr; | 1150 | volatile uint32_t *ptr; |
1151 | u64 gpu_addr; | ||
1151 | }; | 1152 | }; |
1152 | 1153 | ||
1153 | /* | 1154 | /* |
@@ -1219,7 +1220,7 @@ struct radeon_device { | |||
1219 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ | 1220 | const struct firmware *rlc_fw; /* r6/700 RLC firmware */ |
1220 | const struct firmware *mc_fw; /* NI MC firmware */ | 1221 | const struct firmware *mc_fw; /* NI MC firmware */ |
1221 | struct r600_blit r600_blit; | 1222 | struct r600_blit r600_blit; |
1222 | struct r700_vram_scratch vram_scratch; | 1223 | struct r600_vram_scratch vram_scratch; |
1223 | int msi_enabled; /* msi enabled */ | 1224 | int msi_enabled; /* msi enabled */ |
1224 | struct r600_ih ih; /* r6/700 interrupt ring */ | 1225 | struct r600_ih ih; /* r6/700 interrupt ring */ |
1225 | struct work_struct hotplug_work; | 1226 | struct work_struct hotplug_work; |
@@ -1468,6 +1469,12 @@ extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); | |||
1468 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); | 1469 | extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size); |
1469 | 1470 | ||
1470 | /* | 1471 | /* |
1472 | * R600 vram scratch functions | ||
1473 | */ | ||
1474 | int r600_vram_scratch_init(struct radeon_device *rdev); | ||
1475 | void r600_vram_scratch_fini(struct radeon_device *rdev); | ||
1476 | |||
1477 | /* | ||
1471 | * r600 functions used by radeon_encoder.c | 1478 | * r600 functions used by radeon_encoder.c |
1472 | */ | 1479 | */ |
1473 | extern void r600_hdmi_enable(struct drm_encoder *encoder); | 1480 | extern void r600_hdmi_enable(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 87cc1feee3ac..a09049d15901 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -282,7 +282,7 @@ static void rv770_mc_program(struct radeon_device *rdev) | |||
282 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, | 282 | WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, |
283 | rdev->mc.vram_end >> 12); | 283 | rdev->mc.vram_end >> 12); |
284 | } | 284 | } |
285 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); | 285 | WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); |
286 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; | 286 | tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; |
287 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); | 287 | tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); |
288 | WREG32(MC_VM_FB_LOCATION, tmp); | 288 | WREG32(MC_VM_FB_LOCATION, tmp); |
@@ -959,54 +959,6 @@ static void rv770_gpu_init(struct radeon_device *rdev) | |||
959 | 959 | ||
960 | } | 960 | } |
961 | 961 | ||
962 | static int rv770_vram_scratch_init(struct radeon_device *rdev) | ||
963 | { | ||
964 | int r; | ||
965 | u64 gpu_addr; | ||
966 | |||
967 | if (rdev->vram_scratch.robj == NULL) { | ||
968 | r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, | ||
969 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM, | ||
970 | &rdev->vram_scratch.robj); | ||
971 | if (r) { | ||
972 | return r; | ||
973 | } | ||
974 | } | ||
975 | |||
976 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
977 | if (unlikely(r != 0)) | ||
978 | return r; | ||
979 | r = radeon_bo_pin(rdev->vram_scratch.robj, | ||
980 | RADEON_GEM_DOMAIN_VRAM, &gpu_addr); | ||
981 | if (r) { | ||
982 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
983 | return r; | ||
984 | } | ||
985 | r = radeon_bo_kmap(rdev->vram_scratch.robj, | ||
986 | (void **)&rdev->vram_scratch.ptr); | ||
987 | if (r) | ||
988 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
989 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
990 | |||
991 | return r; | ||
992 | } | ||
993 | |||
994 | static void rv770_vram_scratch_fini(struct radeon_device *rdev) | ||
995 | { | ||
996 | int r; | ||
997 | |||
998 | if (rdev->vram_scratch.robj == NULL) { | ||
999 | return; | ||
1000 | } | ||
1001 | r = radeon_bo_reserve(rdev->vram_scratch.robj, false); | ||
1002 | if (likely(r == 0)) { | ||
1003 | radeon_bo_kunmap(rdev->vram_scratch.robj); | ||
1004 | radeon_bo_unpin(rdev->vram_scratch.robj); | ||
1005 | radeon_bo_unreserve(rdev->vram_scratch.robj); | ||
1006 | } | ||
1007 | radeon_bo_unref(&rdev->vram_scratch.robj); | ||
1008 | } | ||
1009 | |||
1010 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 962 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
1011 | { | 963 | { |
1012 | u64 size_bf, size_af; | 964 | u64 size_bf, size_af; |
@@ -1106,6 +1058,10 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1106 | } | 1058 | } |
1107 | } | 1059 | } |
1108 | 1060 | ||
1061 | r = r600_vram_scratch_init(rdev); | ||
1062 | if (r) | ||
1063 | return r; | ||
1064 | |||
1109 | rv770_mc_program(rdev); | 1065 | rv770_mc_program(rdev); |
1110 | if (rdev->flags & RADEON_IS_AGP) { | 1066 | if (rdev->flags & RADEON_IS_AGP) { |
1111 | rv770_agp_enable(rdev); | 1067 | rv770_agp_enable(rdev); |
@@ -1114,9 +1070,7 @@ static int rv770_startup(struct radeon_device *rdev) | |||
1114 | if (r) | 1070 | if (r) |
1115 | return r; | 1071 | return r; |
1116 | } | 1072 | } |
1117 | r = rv770_vram_scratch_init(rdev); | 1073 | |
1118 | if (r) | ||
1119 | return r; | ||
1120 | rv770_gpu_init(rdev); | 1074 | rv770_gpu_init(rdev); |
1121 | r = r600_blit_init(rdev); | 1075 | r = r600_blit_init(rdev); |
1122 | if (r) { | 1076 | if (r) { |
@@ -1316,7 +1270,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1316 | radeon_ib_pool_fini(rdev); | 1270 | radeon_ib_pool_fini(rdev); |
1317 | radeon_irq_kms_fini(rdev); | 1271 | radeon_irq_kms_fini(rdev); |
1318 | rv770_pcie_gart_fini(rdev); | 1272 | rv770_pcie_gart_fini(rdev); |
1319 | rv770_vram_scratch_fini(rdev); | 1273 | r600_vram_scratch_fini(rdev); |
1320 | radeon_gem_fini(rdev); | 1274 | radeon_gem_fini(rdev); |
1321 | radeon_fence_driver_fini(rdev); | 1275 | radeon_fence_driver_fini(rdev); |
1322 | radeon_agp_fini(rdev); | 1276 | radeon_agp_fini(rdev); |