drm/radeon/kms: clear confusion in GART init/deinit path
GART static one time initialization was mixed up with GART
enabling/disabling which could happen several time for instance
during suspend/resume cycles. This patch splits all GART
handling into 4 differents function. gart_init is for one
time initialization, gart_deinit is called upon module unload
to free resources allocated by gart_init, gart_enable enable
the GART and is intented to be call after first initialization
and at each resume cycle or reset cycle. Finaly gart_disable
stop the GART and is intended to be call at suspend time or
when unloading the module.
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index e1e4ce4..a3fbdad 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -92,20 +92,41 @@
WREG32_MC(RS480_GART_CACHE_CNTRL, 0);
}
+int rs400_gart_init(struct radeon_device *rdev)
+{
+ int r;
+
+ if (rdev->gart.table.ram.ptr) {
+ WARN(1, "RS400 GART already initialized.\n");
+ return 0;
+ }
+ /* Check gart size */
+ switch(rdev->mc.gtt_size / (1024 * 1024)) {
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ case 512:
+ case 1024:
+ case 2048:
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* Initialize common gart structure */
+ r = radeon_gart_init(rdev);
+ if (r)
+ return r;
+ if (rs400_debugfs_pcie_gart_info_init(rdev))
+ DRM_ERROR("Failed to register debugfs file for RS400 GART !\n");
+ rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
+ return radeon_gart_table_ram_alloc(rdev);
+}
+
int rs400_gart_enable(struct radeon_device *rdev)
{
uint32_t size_reg;
uint32_t tmp;
- int r;
-
- /* Initialize common gart structure */
- r = radeon_gart_init(rdev);
- if (r) {
- return r;
- }
- if (rs400_debugfs_pcie_gart_info_init(rdev)) {
- DRM_ERROR("Failed to register debugfs file for RS400 GART !\n");
- }
tmp = RREG32_MC(RS690_AIC_CTRL_SCRATCH);
tmp |= RS690_DIS_OUT_OF_PCI_GART_ACCESS;
@@ -136,13 +157,6 @@
default:
return -EINVAL;
}
- if (rdev->gart.table.ram.ptr == NULL) {
- rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
- r = radeon_gart_table_ram_alloc(rdev);
- if (r) {
- return r;
- }
- }
/* It should be fine to program it to max value */
if (rdev->family == CHIP_RS690 || (rdev->family == CHIP_RS740)) {
WREG32_MC(RS690_MCCFG_AGP_BASE, 0xFFFFFFFF);
@@ -201,6 +215,13 @@
WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, 0);
}
+void rs400_gart_fini(struct radeon_device *rdev)
+{
+ rs400_gart_disable(rdev);
+ radeon_gart_table_ram_free(rdev);
+ radeon_gart_fini(rdev);
+}
+
int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
{
uint32_t entry;
@@ -255,14 +276,12 @@
(void)RREG32(RADEON_HOST_PATH_CNTL);
WREG32(RADEON_HOST_PATH_CNTL, tmp);
(void)RREG32(RADEON_HOST_PATH_CNTL);
+
return 0;
}
void rs400_mc_fini(struct radeon_device *rdev)
{
- rs400_gart_disable(rdev);
- radeon_gart_table_ram_free(rdev);
- radeon_gart_fini(rdev);
}