aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r520.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-09-28 14:39:19 -0400
committerDave Airlie <airlied@linux.ie>2009-09-28 21:15:56 -0400
commitf0ed1f655aa0375e2abba84cc4e8e6c853d48555 (patch)
treec7b6495e7836e333a82262e9c9cf0af716e80fc7 /drivers/gpu/drm/radeon/r520.c
parentd39c3b895876427c5083a936e00f3f5b7f0fc1b3 (diff)
drm/radeon/kms: Convert R520 to new init path and associated cleanup
Convert the r520 asic support to new init path, change are smaller than previous one as most of the architecture is now in place and more code sharing can happen btw various asics. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/gpu/drm/radeon/r520.c')
-rw-r--r--drivers/gpu/drm/radeon/r520.c267
1 files changed, 162 insertions, 105 deletions
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 2723486ad380..0bf13fccdaf2 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -26,107 +26,13 @@
26 * Jerome Glisse 26 * Jerome Glisse
27 */ 27 */
28#include "drmP.h" 28#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h" 29#include "radeon.h"
30#include "atom.h"
31#include "r520d.h"
31 32
32/* r520,rv530,rv560,rv570,r580 depends on : */ 33/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */
33void r100_hdp_reset(struct radeon_device *rdev);
34void r420_pipes_init(struct radeon_device *rdev);
35void rs600_mc_disable_clients(struct radeon_device *rdev);
36int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
37int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
38 34
39/* This files gather functions specifics to: 35static int r520_mc_wait_for_idle(struct radeon_device *rdev)
40 * r520,rv530,rv560,rv570,r580
41 *
42 * Some of these functions might be used by newer ASICs.
43 */
44void r520_gpu_init(struct radeon_device *rdev);
45int r520_mc_wait_for_idle(struct radeon_device *rdev);
46
47
48/*
49 * MC
50 */
51int r520_mc_init(struct radeon_device *rdev)
52{
53 uint32_t tmp;
54 int r;
55
56 if (r100_debugfs_rbbm_init(rdev)) {
57 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
58 }
59 if (rv515_debugfs_pipes_info_init(rdev)) {
60 DRM_ERROR("Failed to register debugfs file for pipes !\n");
61 }
62 if (rv515_debugfs_ga_info_init(rdev)) {
63 DRM_ERROR("Failed to register debugfs file for pipes !\n");
64 }
65
66 r520_gpu_init(rdev);
67 rv370_pcie_gart_disable(rdev);
68
69 /* Setup GPU memory space */
70 rdev->mc.vram_location = 0xFFFFFFFFUL;
71 rdev->mc.gtt_location = 0xFFFFFFFFUL;
72 if (rdev->flags & RADEON_IS_AGP) {
73 r = radeon_agp_init(rdev);
74 if (r) {
75 printk(KERN_WARNING "[drm] Disabling AGP\n");
76 rdev->flags &= ~RADEON_IS_AGP;
77 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
78 } else {
79 rdev->mc.gtt_location = rdev->mc.agp_base;
80 }
81 }
82 r = radeon_mc_setup(rdev);
83 if (r) {
84 return r;
85 }
86
87 /* Program GPU memory space */
88 rs600_mc_disable_clients(rdev);
89 if (r520_mc_wait_for_idle(rdev)) {
90 printk(KERN_WARNING "Failed to wait MC idle while "
91 "programming pipes. Bad things might happen.\n");
92 }
93 /* Write VRAM size in case we are limiting it */
94 WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
95 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
96 tmp = REG_SET(R520_MC_FB_TOP, tmp >> 16);
97 tmp |= REG_SET(R520_MC_FB_START, rdev->mc.vram_location >> 16);
98 WREG32_MC(R520_MC_FB_LOCATION, tmp);
99 WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
100 WREG32(0x310, rdev->mc.vram_location);
101 if (rdev->flags & RADEON_IS_AGP) {
102 tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
103 tmp = REG_SET(R520_MC_AGP_TOP, tmp >> 16);
104 tmp |= REG_SET(R520_MC_AGP_START, rdev->mc.gtt_location >> 16);
105 WREG32_MC(R520_MC_AGP_LOCATION, tmp);
106 WREG32_MC(R520_MC_AGP_BASE, rdev->mc.agp_base);
107 WREG32_MC(R520_MC_AGP_BASE_2, 0);
108 } else {
109 WREG32_MC(R520_MC_AGP_LOCATION, 0x0FFFFFFF);
110 WREG32_MC(R520_MC_AGP_BASE, 0);
111 WREG32_MC(R520_MC_AGP_BASE_2, 0);
112 }
113 return 0;
114}
115
116void r520_mc_fini(struct radeon_device *rdev)
117{
118}
119
120
121/*
122 * Global GPU functions
123 */
124void r520_errata(struct radeon_device *rdev)
125{
126 rdev->pll_errata = 0;
127}
128
129int r520_mc_wait_for_idle(struct radeon_device *rdev)
130{ 36{
131 unsigned i; 37 unsigned i;
132 uint32_t tmp; 38 uint32_t tmp;
@@ -142,7 +48,7 @@ int r520_mc_wait_for_idle(struct radeon_device *rdev)
142 return -1; 48 return -1;
143} 49}
144 50
145void r520_gpu_init(struct radeon_device *rdev) 51static void r520_gpu_init(struct radeon_device *rdev)
146{ 52{
147 unsigned pipe_select_current, gb_pipe_select, tmp; 53 unsigned pipe_select_current, gb_pipe_select, tmp;
148 54
@@ -185,10 +91,6 @@ void r520_gpu_init(struct radeon_device *rdev)
185 } 91 }
186} 92}
187 93
188
189/*
190 * VRAM info
191 */
192static void r520_vram_get_type(struct radeon_device *rdev) 94static void r520_vram_get_type(struct radeon_device *rdev)
193{ 95{
194 uint32_t tmp; 96 uint32_t tmp;
@@ -232,13 +134,168 @@ void r520_vram_info(struct radeon_device *rdev)
232 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); 134 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
233} 135}
234 136
235void r520_bandwidth_update(struct radeon_device *rdev) 137void r520_mc_program(struct radeon_device *rdev)
138{
139 struct rv515_mc_save save;
140
141 /* Stops all mc clients */
142 rv515_mc_stop(rdev, &save);
143
144 /* Wait for mc idle */
145 if (r520_mc_wait_for_idle(rdev))
146 dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
147 /* Write VRAM size in case we are limiting it */
148 WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
149 /* Program MC, should be a 32bits limited address space */
150 WREG32_MC(R_000004_MC_FB_LOCATION,
151 S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
152 S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
153 WREG32(R_000134_HDP_FB_LOCATION,
154 S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
155 if (rdev->flags & RADEON_IS_AGP) {
156 WREG32_MC(R_000005_MC_AGP_LOCATION,
157 S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) |
158 S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
159 WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
160 WREG32_MC(R_000007_AGP_BASE_2,
161 S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));
162 } else {
163 WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF);
164 WREG32_MC(R_000006_AGP_BASE, 0);
165 WREG32_MC(R_000007_AGP_BASE_2, 0);
166 }
167
168 rv515_mc_resume(rdev, &save);
169}
170
171static int r520_startup(struct radeon_device *rdev)
172{
173 int r;
174
175 r520_mc_program(rdev);
176 /* Resume clock */
177 rv515_clock_startup(rdev);
178 /* Initialize GPU configuration (# pipes, ...) */
179 r520_gpu_init(rdev);
180 /* Initialize GART (initialize after TTM so we can allocate
181 * memory through TTM but finalize after TTM) */
182 if (rdev->flags & RADEON_IS_PCIE) {
183 r = rv370_pcie_gart_enable(rdev);
184 if (r)
185 return r;
186 }
187 /* Enable IRQ */
188 rdev->irq.sw_int = true;
189 r100_irq_set(rdev);
190 /* 1M ring buffer */
191 r = r100_cp_init(rdev, 1024 * 1024);
192 if (r) {
193 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
194 return r;
195 }
196 r = r100_wb_init(rdev);
197 if (r)
198 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
199 r = r100_ib_init(rdev);
200 if (r) {
201 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
202 return r;
203 }
204 return 0;
205}
206
207int r520_resume(struct radeon_device *rdev)
236{ 208{
237 rv515_bandwidth_avivo_update(rdev); 209 /* Make sur GART are not working */
210 if (rdev->flags & RADEON_IS_PCIE)
211 rv370_pcie_gart_disable(rdev);
212 /* Resume clock before doing reset */
213 rv515_clock_startup(rdev);
214 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
215 if (radeon_gpu_reset(rdev)) {
216 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
217 RREG32(R_000E40_RBBM_STATUS),
218 RREG32(R_0007C0_CP_STAT));
219 }
220 /* post */
221 atom_asic_init(rdev->mode_info.atom_context);
222 /* Resume clock after posting */
223 rv515_clock_startup(rdev);
224 return r520_startup(rdev);
238} 225}
239 226
240int r520_init(struct radeon_device *rdev) 227int r520_init(struct radeon_device *rdev)
241{ 228{
229 int r;
230
231 rdev->new_init_path = true;
232 /* Initialize scratch registers */
233 radeon_scratch_init(rdev);
234 /* Initialize surface registers */
235 radeon_surface_init(rdev);
236 /* TODO: disable VGA need to use VGA request */
237 /* BIOS*/
238 if (!radeon_get_bios(rdev)) {
239 if (ASIC_IS_AVIVO(rdev))
240 return -EINVAL;
241 }
242 if (rdev->is_atom_bios) {
243 r = radeon_atombios_init(rdev);
244 if (r)
245 return r;
246 } else {
247 dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
248 return -EINVAL;
249 }
250 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
251 if (radeon_gpu_reset(rdev)) {
252 dev_warn(rdev->dev,
253 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
254 RREG32(R_000E40_RBBM_STATUS),
255 RREG32(R_0007C0_CP_STAT));
256 }
257 /* check if cards are posted or not */
258 if (!radeon_card_posted(rdev) && rdev->bios) {
259 DRM_INFO("GPU not posted. posting now...\n");
260 atom_asic_init(rdev->mode_info.atom_context);
261 }
262 /* Initialize clocks */
263 radeon_get_clock_info(rdev->ddev);
264 /* Get vram informations */
265 r520_vram_info(rdev);
266 /* Initialize memory controller (also test AGP) */
267 r = r420_mc_init(rdev);
268 if (r)
269 return r;
270 rv515_debugfs(rdev);
271 /* Fence driver */
272 r = radeon_fence_driver_init(rdev);
273 if (r)
274 return r;
275 r = radeon_irq_kms_init(rdev);
276 if (r)
277 return r;
278 /* Memory manager */
279 r = radeon_object_init(rdev);
280 if (r)
281 return r;
282 r = rv370_pcie_gart_init(rdev);
283 if (r)
284 return r;
242 rv515_set_safe_registers(rdev); 285 rv515_set_safe_registers(rdev);
286 rdev->accel_working = true;
287 r = r520_startup(rdev);
288 if (r) {
289 /* Somethings want wront with the accel init stop accel */
290 dev_err(rdev->dev, "Disabling GPU acceleration\n");
291 rv515_suspend(rdev);
292 r100_cp_fini(rdev);
293 r100_wb_fini(rdev);
294 r100_ib_fini(rdev);
295 rv370_pcie_gart_fini(rdev);
296 radeon_agp_fini(rdev);
297 radeon_irq_kms_fini(rdev);
298 rdev->accel_working = false;
299 }
243 return 0; 300 return 0;
244} 301}