diff options
author | Jerome Glisse <jglisse@redhat.com> | 2009-09-14 12:29:49 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-14 18:53:14 -0400 |
commit | 4aac047323e3082d0866b8ad3784236632105af4 (patch) | |
tree | af4c118e42b9ea55c961c4f5bbb02998dc2cc4fe /drivers/gpu/drm/radeon/r300.c | |
parent | 21f9a437222e92adb3abc68584a5f04801b92739 (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/radeon/r300.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 108 |
1 files changed, 45 insertions, 63 deletions
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index ced3322bd5fb..bb151ecdf8fc 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -42,7 +42,6 @@ int r100_cp_reset(struct radeon_device *rdev); | |||
42 | int r100_rb2d_reset(struct radeon_device *rdev); | 42 | int r100_rb2d_reset(struct radeon_device *rdev); |
43 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); | 43 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); |
44 | int r100_pci_gart_enable(struct radeon_device *rdev); | 44 | int r100_pci_gart_enable(struct radeon_device *rdev); |
45 | void r100_pci_gart_disable(struct radeon_device *rdev); | ||
46 | void r100_mc_setup(struct radeon_device *rdev); | 45 | void r100_mc_setup(struct radeon_device *rdev); |
47 | void r100_mc_disable_clients(struct radeon_device *rdev); | 46 | void r100_mc_disable_clients(struct radeon_device *rdev); |
48 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | 47 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
@@ -86,26 +85,57 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
86 | mb(); | 85 | mb(); |
87 | } | 86 | } |
88 | 87 | ||
89 | int rv370_pcie_gart_enable(struct radeon_device *rdev) | 88 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
89 | { | ||
90 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | ||
91 | |||
92 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | ||
93 | return -EINVAL; | ||
94 | } | ||
95 | addr = (lower_32_bits(addr) >> 8) | | ||
96 | ((upper_32_bits(addr) & 0xff) << 24) | | ||
97 | 0xc; | ||
98 | /* on x86 we want this to be CPU endian, on powerpc | ||
99 | * on powerpc without HW swappers, it'll get swapped on way | ||
100 | * into VRAM - so no need for cpu_to_le32 on VRAM tables */ | ||
101 | writel(addr, ((void __iomem *)ptr) + (i * 4)); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | int rv370_pcie_gart_init(struct radeon_device *rdev) | ||
90 | { | 106 | { |
91 | uint32_t table_addr; | ||
92 | uint32_t tmp; | ||
93 | int r; | 107 | int r; |
94 | 108 | ||
109 | if (rdev->gart.table.vram.robj) { | ||
110 | WARN(1, "RV370 PCIE GART already initialized.\n"); | ||
111 | return 0; | ||
112 | } | ||
95 | /* Initialize common gart structure */ | 113 | /* Initialize common gart structure */ |
96 | r = radeon_gart_init(rdev); | 114 | r = radeon_gart_init(rdev); |
97 | if (r) { | 115 | if (r) |
98 | return r; | 116 | return r; |
99 | } | ||
100 | r = rv370_debugfs_pcie_gart_info_init(rdev); | 117 | r = rv370_debugfs_pcie_gart_info_init(rdev); |
101 | if (r) { | 118 | if (r) |
102 | DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); | 119 | DRM_ERROR("Failed to register debugfs file for PCIE gart !\n"); |
103 | } | ||
104 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; | 120 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
105 | r = radeon_gart_table_vram_alloc(rdev); | 121 | rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; |
106 | if (r) { | 122 | rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; |
107 | return r; | 123 | return radeon_gart_table_vram_alloc(rdev); |
124 | } | ||
125 | |||
126 | int rv370_pcie_gart_enable(struct radeon_device *rdev) | ||
127 | { | ||
128 | uint32_t table_addr; | ||
129 | uint32_t tmp; | ||
130 | int r; | ||
131 | |||
132 | if (rdev->gart.table.vram.robj == NULL) { | ||
133 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); | ||
134 | return -EINVAL; | ||
108 | } | 135 | } |
136 | r = radeon_gart_table_vram_pin(rdev); | ||
137 | if (r) | ||
138 | return r; | ||
109 | /* discard memory request outside of configured range */ | 139 | /* discard memory request outside of configured range */ |
110 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; | 140 | tmp = RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD; |
111 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); | 141 | WREG32_PCIE(RADEON_PCIE_TX_GART_CNTL, tmp); |
@@ -145,51 +175,13 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) | |||
145 | } | 175 | } |
146 | } | 176 | } |
147 | 177 | ||
148 | int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) | 178 | void rv370_pcie_gart_fini(struct radeon_device *rdev) |
149 | { | ||
150 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | ||
151 | |||
152 | if (i < 0 || i > rdev->gart.num_gpu_pages) { | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | addr = (lower_32_bits(addr) >> 8) | | ||
156 | ((upper_32_bits(addr) & 0xff) << 24) | | ||
157 | 0xc; | ||
158 | /* on x86 we want this to be CPU endian, on powerpc | ||
159 | * on powerpc without HW swappers, it'll get swapped on way | ||
160 | * into VRAM - so no need for cpu_to_le32 on VRAM tables */ | ||
161 | writel(addr, ((void __iomem *)ptr) + (i * 4)); | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | int r300_gart_enable(struct radeon_device *rdev) | ||
166 | { | 179 | { |
167 | #if __OS_HAS_AGP | 180 | rv370_pcie_gart_disable(rdev); |
168 | if (rdev->flags & RADEON_IS_AGP) { | 181 | radeon_gart_table_vram_free(rdev); |
169 | if (rdev->family > CHIP_RV350) { | 182 | radeon_gart_fini(rdev); |
170 | rv370_pcie_gart_disable(rdev); | ||
171 | } else { | ||
172 | r100_pci_gart_disable(rdev); | ||
173 | } | ||
174 | return 0; | ||
175 | } | ||
176 | #endif | ||
177 | if (rdev->flags & RADEON_IS_PCIE) { | ||
178 | rdev->asic->gart_disable = &rv370_pcie_gart_disable; | ||
179 | rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush; | ||
180 | rdev->asic->gart_set_page = &rv370_pcie_gart_set_page; | ||
181 | return rv370_pcie_gart_enable(rdev); | ||
182 | } | ||
183 | if (rdev->flags & RADEON_IS_PCI) { | ||
184 | rdev->asic->gart_disable = &r100_pci_gart_disable; | ||
185 | rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; | ||
186 | rdev->asic->gart_set_page = &r100_pci_gart_set_page; | ||
187 | return r100_pci_gart_enable(rdev); | ||
188 | } | ||
189 | return r100_pci_gart_enable(rdev); | ||
190 | } | 183 | } |
191 | 184 | ||
192 | |||
193 | /* | 185 | /* |
194 | * MC | 186 | * MC |
195 | */ | 187 | */ |
@@ -237,14 +229,6 @@ int r300_mc_init(struct radeon_device *rdev) | |||
237 | 229 | ||
238 | void r300_mc_fini(struct radeon_device *rdev) | 230 | void r300_mc_fini(struct radeon_device *rdev) |
239 | { | 231 | { |
240 | if (rdev->flags & RADEON_IS_PCIE) { | ||
241 | rv370_pcie_gart_disable(rdev); | ||
242 | radeon_gart_table_vram_free(rdev); | ||
243 | } else { | ||
244 | r100_pci_gart_disable(rdev); | ||
245 | radeon_gart_table_ram_free(rdev); | ||
246 | } | ||
247 | radeon_gart_fini(rdev); | ||
248 | } | 232 | } |
249 | 233 | ||
250 | 234 | ||
@@ -1299,8 +1283,6 @@ void r300_mc_program(struct radeon_device *rdev) | |||
1299 | 1283 | ||
1300 | /* Stops all mc clients */ | 1284 | /* Stops all mc clients */ |
1301 | r100_mc_stop(rdev, &save); | 1285 | r100_mc_stop(rdev, &save); |
1302 | /* Shutdown PCI/PCIE GART */ | ||
1303 | radeon_gart_disable(rdev); | ||
1304 | if (rdev->flags & RADEON_IS_AGP) { | 1286 | if (rdev->flags & RADEON_IS_AGP) { |
1305 | WREG32(R_00014C_MC_AGP_LOCATION, | 1287 | WREG32(R_00014C_MC_AGP_LOCATION, |
1306 | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | | 1288 | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | |