blob: 4facbab2045660b0033ef8530a5d50a88b26d798 [file] [log] [blame]
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +100028#include <linux/seq_file.h>
29#include <linux/firmware.h>
30#include <linux/platform_device.h>
Jerome Glisse771fe6b2009-06-05 14:42:42 +020031#include "drmP.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100032#include "radeon_drm.h"
Jerome Glisse771fe6b2009-06-05 14:42:42 +020033#include "radeon.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100034#include "radeon_mode.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100035#include "r600d.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100036#include "atom.h"
Jerome Glissed39c3b82009-09-28 18:34:43 +020037#include "avivod.h"
Jerome Glisse771fe6b2009-06-05 14:42:42 +020038
Jerome Glisse3ce0a232009-09-08 10:10:24 +100039#define PFP_UCODE_SIZE 576
40#define PM4_UCODE_SIZE 1792
Alex Deucherd8f60cf2009-12-01 13:43:46 -050041#define RLC_UCODE_SIZE 768
Jerome Glisse3ce0a232009-09-08 10:10:24 +100042#define R700_PFP_UCODE_SIZE 848
43#define R700_PM4_UCODE_SIZE 1360
Alex Deucherd8f60cf2009-12-01 13:43:46 -050044#define R700_RLC_UCODE_SIZE 1024
Jerome Glisse3ce0a232009-09-08 10:10:24 +100045
46/* Firmware Names */
47MODULE_FIRMWARE("radeon/R600_pfp.bin");
48MODULE_FIRMWARE("radeon/R600_me.bin");
49MODULE_FIRMWARE("radeon/RV610_pfp.bin");
50MODULE_FIRMWARE("radeon/RV610_me.bin");
51MODULE_FIRMWARE("radeon/RV630_pfp.bin");
52MODULE_FIRMWARE("radeon/RV630_me.bin");
53MODULE_FIRMWARE("radeon/RV620_pfp.bin");
54MODULE_FIRMWARE("radeon/RV620_me.bin");
55MODULE_FIRMWARE("radeon/RV635_pfp.bin");
56MODULE_FIRMWARE("radeon/RV635_me.bin");
57MODULE_FIRMWARE("radeon/RV670_pfp.bin");
58MODULE_FIRMWARE("radeon/RV670_me.bin");
59MODULE_FIRMWARE("radeon/RS780_pfp.bin");
60MODULE_FIRMWARE("radeon/RS780_me.bin");
61MODULE_FIRMWARE("radeon/RV770_pfp.bin");
62MODULE_FIRMWARE("radeon/RV770_me.bin");
63MODULE_FIRMWARE("radeon/RV730_pfp.bin");
64MODULE_FIRMWARE("radeon/RV730_me.bin");
65MODULE_FIRMWARE("radeon/RV710_pfp.bin");
66MODULE_FIRMWARE("radeon/RV710_me.bin");
Alex Deucherd8f60cf2009-12-01 13:43:46 -050067MODULE_FIRMWARE("radeon/R600_rlc.bin");
68MODULE_FIRMWARE("radeon/R700_rlc.bin");
Jerome Glisse3ce0a232009-09-08 10:10:24 +100069
70int r600_debugfs_mc_info_init(struct radeon_device *rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +020071
Jerome Glisse1a029b72009-10-06 19:04:30 +020072/* r600,rv610,rv630,rv620,rv635,rv670 */
Jerome Glisse771fe6b2009-06-05 14:42:42 +020073int r600_mc_wait_for_idle(struct radeon_device *rdev);
74void r600_gpu_init(struct radeon_device *rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +100075void r600_fini(struct radeon_device *rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +020076
Alex Deuchere0df1ac2009-12-04 15:12:21 -050077/* hpd for digital panel detect/disconnect */
78bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
79{
80 bool connected = false;
81
82 if (ASIC_IS_DCE3(rdev)) {
83 switch (hpd) {
84 case RADEON_HPD_1:
85 if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
86 connected = true;
87 break;
88 case RADEON_HPD_2:
89 if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
90 connected = true;
91 break;
92 case RADEON_HPD_3:
93 if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
94 connected = true;
95 break;
96 case RADEON_HPD_4:
97 if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
98 connected = true;
99 break;
100 /* DCE 3.2 */
101 case RADEON_HPD_5:
102 if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
103 connected = true;
104 break;
105 case RADEON_HPD_6:
106 if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
107 connected = true;
108 break;
109 default:
110 break;
111 }
112 } else {
113 switch (hpd) {
114 case RADEON_HPD_1:
115 if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
116 connected = true;
117 break;
118 case RADEON_HPD_2:
119 if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
120 connected = true;
121 break;
122 case RADEON_HPD_3:
123 if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
124 connected = true;
125 break;
126 default:
127 break;
128 }
129 }
130 return connected;
131}
132
133void r600_hpd_set_polarity(struct radeon_device *rdev,
Alex Deucher429770b2009-12-04 15:26:55 -0500134 enum radeon_hpd_id hpd)
Alex Deuchere0df1ac2009-12-04 15:12:21 -0500135{
136 u32 tmp;
137 bool connected = r600_hpd_sense(rdev, hpd);
138
139 if (ASIC_IS_DCE3(rdev)) {
140 switch (hpd) {
141 case RADEON_HPD_1:
142 tmp = RREG32(DC_HPD1_INT_CONTROL);
143 if (connected)
144 tmp &= ~DC_HPDx_INT_POLARITY;
145 else
146 tmp |= DC_HPDx_INT_POLARITY;
147 WREG32(DC_HPD1_INT_CONTROL, tmp);
148 break;
149 case RADEON_HPD_2:
150 tmp = RREG32(DC_HPD2_INT_CONTROL);
151 if (connected)
152 tmp &= ~DC_HPDx_INT_POLARITY;
153 else
154 tmp |= DC_HPDx_INT_POLARITY;
155 WREG32(DC_HPD2_INT_CONTROL, tmp);
156 break;
157 case RADEON_HPD_3:
158 tmp = RREG32(DC_HPD3_INT_CONTROL);
159 if (connected)
160 tmp &= ~DC_HPDx_INT_POLARITY;
161 else
162 tmp |= DC_HPDx_INT_POLARITY;
163 WREG32(DC_HPD3_INT_CONTROL, tmp);
164 break;
165 case RADEON_HPD_4:
166 tmp = RREG32(DC_HPD4_INT_CONTROL);
167 if (connected)
168 tmp &= ~DC_HPDx_INT_POLARITY;
169 else
170 tmp |= DC_HPDx_INT_POLARITY;
171 WREG32(DC_HPD4_INT_CONTROL, tmp);
172 break;
173 case RADEON_HPD_5:
174 tmp = RREG32(DC_HPD5_INT_CONTROL);
175 if (connected)
176 tmp &= ~DC_HPDx_INT_POLARITY;
177 else
178 tmp |= DC_HPDx_INT_POLARITY;
179 WREG32(DC_HPD5_INT_CONTROL, tmp);
180 break;
181 /* DCE 3.2 */
182 case RADEON_HPD_6:
183 tmp = RREG32(DC_HPD6_INT_CONTROL);
184 if (connected)
185 tmp &= ~DC_HPDx_INT_POLARITY;
186 else
187 tmp |= DC_HPDx_INT_POLARITY;
188 WREG32(DC_HPD6_INT_CONTROL, tmp);
189 break;
190 default:
191 break;
192 }
193 } else {
194 switch (hpd) {
195 case RADEON_HPD_1:
196 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
197 if (connected)
198 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
199 else
200 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
201 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
202 break;
203 case RADEON_HPD_2:
204 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
205 if (connected)
206 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
207 else
208 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
209 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
210 break;
211 case RADEON_HPD_3:
212 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
213 if (connected)
214 tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
215 else
216 tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
217 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
218 break;
219 default:
220 break;
221 }
222 }
223}
224
225void r600_hpd_init(struct radeon_device *rdev)
226{
227 struct drm_device *dev = rdev->ddev;
228 struct drm_connector *connector;
229
230 if (ASIC_IS_DCE3(rdev)) {
231 u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
232 if (ASIC_IS_DCE32(rdev))
233 tmp |= DC_HPDx_EN;
234
235 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
236 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
237 switch (radeon_connector->hpd.hpd) {
238 case RADEON_HPD_1:
239 WREG32(DC_HPD1_CONTROL, tmp);
240 rdev->irq.hpd[0] = true;
241 break;
242 case RADEON_HPD_2:
243 WREG32(DC_HPD2_CONTROL, tmp);
244 rdev->irq.hpd[1] = true;
245 break;
246 case RADEON_HPD_3:
247 WREG32(DC_HPD3_CONTROL, tmp);
248 rdev->irq.hpd[2] = true;
249 break;
250 case RADEON_HPD_4:
251 WREG32(DC_HPD4_CONTROL, tmp);
252 rdev->irq.hpd[3] = true;
253 break;
254 /* DCE 3.2 */
255 case RADEON_HPD_5:
256 WREG32(DC_HPD5_CONTROL, tmp);
257 rdev->irq.hpd[4] = true;
258 break;
259 case RADEON_HPD_6:
260 WREG32(DC_HPD6_CONTROL, tmp);
261 rdev->irq.hpd[5] = true;
262 break;
263 default:
264 break;
265 }
266 }
267 } else {
268 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
269 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
270 switch (radeon_connector->hpd.hpd) {
271 case RADEON_HPD_1:
272 WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
273 rdev->irq.hpd[0] = true;
274 break;
275 case RADEON_HPD_2:
276 WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
277 rdev->irq.hpd[1] = true;
278 break;
279 case RADEON_HPD_3:
280 WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
281 rdev->irq.hpd[2] = true;
282 break;
283 default:
284 break;
285 }
286 }
287 }
Jerome Glisse003e69f2010-01-07 15:39:14 +0100288 if (rdev->irq.installed)
289 r600_irq_set(rdev);
Alex Deuchere0df1ac2009-12-04 15:12:21 -0500290}
291
292void r600_hpd_fini(struct radeon_device *rdev)
293{
294 struct drm_device *dev = rdev->ddev;
295 struct drm_connector *connector;
296
297 if (ASIC_IS_DCE3(rdev)) {
298 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
299 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
300 switch (radeon_connector->hpd.hpd) {
301 case RADEON_HPD_1:
302 WREG32(DC_HPD1_CONTROL, 0);
303 rdev->irq.hpd[0] = false;
304 break;
305 case RADEON_HPD_2:
306 WREG32(DC_HPD2_CONTROL, 0);
307 rdev->irq.hpd[1] = false;
308 break;
309 case RADEON_HPD_3:
310 WREG32(DC_HPD3_CONTROL, 0);
311 rdev->irq.hpd[2] = false;
312 break;
313 case RADEON_HPD_4:
314 WREG32(DC_HPD4_CONTROL, 0);
315 rdev->irq.hpd[3] = false;
316 break;
317 /* DCE 3.2 */
318 case RADEON_HPD_5:
319 WREG32(DC_HPD5_CONTROL, 0);
320 rdev->irq.hpd[4] = false;
321 break;
322 case RADEON_HPD_6:
323 WREG32(DC_HPD6_CONTROL, 0);
324 rdev->irq.hpd[5] = false;
325 break;
326 default:
327 break;
328 }
329 }
330 } else {
331 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
332 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
333 switch (radeon_connector->hpd.hpd) {
334 case RADEON_HPD_1:
335 WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
336 rdev->irq.hpd[0] = false;
337 break;
338 case RADEON_HPD_2:
339 WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
340 rdev->irq.hpd[1] = false;
341 break;
342 case RADEON_HPD_3:
343 WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
344 rdev->irq.hpd[2] = false;
345 break;
346 default:
347 break;
348 }
349 }
350 }
351}
352
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200353/*
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000354 * R600 PCIE GART
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200355 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000356int r600_gart_clear_page(struct radeon_device *rdev, int i)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200357{
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000358 void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
359 u64 pte;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200360
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000361 if (i < 0 || i > rdev->gart.num_gpu_pages)
362 return -EINVAL;
363 pte = 0;
364 writeq(pte, ((void __iomem *)ptr) + (i * 8));
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200365 return 0;
366}
367
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000368void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200369{
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000370 unsigned i;
371 u32 tmp;
372
373 WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
374 WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
375 WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
376 for (i = 0; i < rdev->usec_timeout; i++) {
377 /* read MC_STATUS */
378 tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
379 tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
380 if (tmp == 2) {
381 printk(KERN_WARNING "[drm] r600 flush TLB failed\n");
382 return;
383 }
384 if (tmp) {
385 return;
386 }
387 udelay(1);
388 }
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200389}
390
Jerome Glisse4aac0472009-09-14 18:29:49 +0200391int r600_pcie_gart_init(struct radeon_device *rdev)
392{
393 int r;
394
395 if (rdev->gart.table.vram.robj) {
396 WARN(1, "R600 PCIE GART already initialized.\n");
397 return 0;
398 }
399 /* Initialize common gart structure */
400 r = radeon_gart_init(rdev);
401 if (r)
402 return r;
403 rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
404 return radeon_gart_table_vram_alloc(rdev);
405}
406
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000407int r600_pcie_gart_enable(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200408{
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000409 u32 tmp;
410 int r, i;
411
Jerome Glisse4aac0472009-09-14 18:29:49 +0200412 if (rdev->gart.table.vram.robj == NULL) {
413 dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
414 return -EINVAL;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000415 }
Jerome Glisse4aac0472009-09-14 18:29:49 +0200416 r = radeon_gart_table_vram_pin(rdev);
417 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000418 return r;
Dave Airlie82568562010-02-05 16:00:07 +1000419 radeon_gart_restore(rdev);
Dave Airliebc1a6312009-09-15 11:07:52 +1000420
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000421 /* Setup L2 cache */
422 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
423 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
424 EFFECTIVE_L2_QUEUE_SIZE(7));
425 WREG32(VM_L2_CNTL2, 0);
426 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
427 /* Setup TLB control */
428 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
429 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
430 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
431 ENABLE_WAIT_L2_QUERY;
432 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
433 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
434 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
435 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
436 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
437 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
438 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
439 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
440 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
441 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
442 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
443 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
444 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
445 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
446 WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200447 WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000448 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
449 WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
450 RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
451 WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
452 (u32)(rdev->dummy_page.addr >> 12));
453 for (i = 1; i < 7; i++)
454 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
455
456 r600_pcie_gart_tlb_flush(rdev);
457 rdev->gart.ready = true;
458 return 0;
459}
460
461void r600_pcie_gart_disable(struct radeon_device *rdev)
462{
463 u32 tmp;
Jerome Glisse4c788672009-11-20 14:29:23 +0100464 int i, r;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000465
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000466 /* Disable all tables */
467 for (i = 0; i < 7; i++)
468 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
469
470 /* Disable L2 cache */
471 WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
472 EFFECTIVE_L2_QUEUE_SIZE(7));
473 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
474 /* Setup L1 TLB control */
475 tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
476 ENABLE_WAIT_L2_QUERY;
477 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
478 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
479 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
480 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
481 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
482 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
483 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
484 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
485 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp);
486 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp);
487 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
488 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
489 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
490 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
Jerome Glisse4aac0472009-09-14 18:29:49 +0200491 if (rdev->gart.table.vram.robj) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100492 r = radeon_bo_reserve(rdev->gart.table.vram.robj, false);
493 if (likely(r == 0)) {
494 radeon_bo_kunmap(rdev->gart.table.vram.robj);
495 radeon_bo_unpin(rdev->gart.table.vram.robj);
496 radeon_bo_unreserve(rdev->gart.table.vram.robj);
497 }
Jerome Glisse4aac0472009-09-14 18:29:49 +0200498 }
499}
500
501void r600_pcie_gart_fini(struct radeon_device *rdev)
502{
503 r600_pcie_gart_disable(rdev);
504 radeon_gart_table_vram_free(rdev);
505 radeon_gart_fini(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200506}
507
Jerome Glisse1a029b72009-10-06 19:04:30 +0200508void r600_agp_enable(struct radeon_device *rdev)
509{
510 u32 tmp;
511 int i;
512
513 /* Setup L2 cache */
514 WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
515 ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
516 EFFECTIVE_L2_QUEUE_SIZE(7));
517 WREG32(VM_L2_CNTL2, 0);
518 WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
519 /* Setup TLB control */
520 tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
521 SYSTEM_ACCESS_MODE_NOT_IN_SYS |
522 EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
523 ENABLE_WAIT_L2_QUERY;
524 WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
525 WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
526 WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
527 WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
528 WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
529 WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
530 WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
531 WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
532 WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
533 WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
534 WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
535 WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
536 WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
537 WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
538 for (i = 0; i < 7; i++)
539 WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
540}
541
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200542int r600_mc_wait_for_idle(struct radeon_device *rdev)
543{
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000544 unsigned i;
545 u32 tmp;
546
547 for (i = 0; i < rdev->usec_timeout; i++) {
548 /* read MC_STATUS */
549 tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00;
550 if (!tmp)
551 return 0;
552 udelay(1);
553 }
554 return -1;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200555}
556
Jerome Glissea3c19452009-10-01 18:02:13 +0200557static void r600_mc_program(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200558{
Jerome Glissea3c19452009-10-01 18:02:13 +0200559 struct rv515_mc_save save;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000560 u32 tmp;
561 int i, j;
562
563 /* Initialize HDP */
564 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
565 WREG32((0x2c14 + j), 0x00000000);
566 WREG32((0x2c18 + j), 0x00000000);
567 WREG32((0x2c1c + j), 0x00000000);
568 WREG32((0x2c20 + j), 0x00000000);
569 WREG32((0x2c24 + j), 0x00000000);
570 }
571 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
572
Jerome Glissea3c19452009-10-01 18:02:13 +0200573 rv515_mc_stop(rdev, &save);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000574 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +0200575 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000576 }
Jerome Glissea3c19452009-10-01 18:02:13 +0200577 /* Lockout access through VGA aperture (doesn't exist before R600) */
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000578 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000579 /* Update configuration */
Jerome Glisse1a029b72009-10-06 19:04:30 +0200580 if (rdev->flags & RADEON_IS_AGP) {
581 if (rdev->mc.vram_start < rdev->mc.gtt_start) {
582 /* VRAM before AGP */
583 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
584 rdev->mc.vram_start >> 12);
585 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
586 rdev->mc.gtt_end >> 12);
587 } else {
588 /* VRAM after AGP */
589 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
590 rdev->mc.gtt_start >> 12);
591 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
592 rdev->mc.vram_end >> 12);
593 }
594 } else {
595 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
596 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
597 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000598 WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200599 tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000600 tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
601 WREG32(MC_VM_FB_LOCATION, tmp);
602 WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
603 WREG32(HDP_NONSURFACE_INFO, (2 << 7));
Jerome Glisse1a029b72009-10-06 19:04:30 +0200604 WREG32(HDP_NONSURFACE_SIZE, rdev->mc.mc_vram_size | 0x3FF);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000605 if (rdev->flags & RADEON_IS_AGP) {
Jerome Glisse1a029b72009-10-06 19:04:30 +0200606 WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
607 WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000608 WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
609 } else {
610 WREG32(MC_VM_AGP_BASE, 0);
611 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
612 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
613 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000614 if (r600_mc_wait_for_idle(rdev)) {
Jerome Glissea3c19452009-10-01 18:02:13 +0200615 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000616 }
Jerome Glissea3c19452009-10-01 18:02:13 +0200617 rv515_mc_resume(rdev, &save);
Dave Airlie698443d2009-09-18 14:16:38 +1000618 /* we need to own VRAM, so turn off the VGA renderer here
619 * to stop it overwriting our objects */
Jerome Glissed39c3b82009-09-28 18:34:43 +0200620 rv515_vga_render_disable(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200621}
622
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000623int r600_mc_init(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200624{
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000625 fixed20_12 a;
626 u32 tmp;
Alex Deucher5885b7a2009-10-19 17:23:33 -0400627 int chansize, numchan;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200628
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000629 /* Get VRAM informations */
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200630 rdev->mc.vram_is_ddr = true;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000631 tmp = RREG32(RAMCFG);
632 if (tmp & CHANSIZE_OVERRIDE) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200633 chansize = 16;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000634 } else if (tmp & CHANSIZE_MASK) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200635 chansize = 64;
636 } else {
637 chansize = 32;
638 }
Alex Deucher5885b7a2009-10-19 17:23:33 -0400639 tmp = RREG32(CHMAP);
640 switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
641 case 0:
642 default:
643 numchan = 1;
644 break;
645 case 1:
646 numchan = 2;
647 break;
648 case 2:
649 numchan = 4;
650 break;
651 case 3:
652 numchan = 8;
653 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200654 }
Alex Deucher5885b7a2009-10-19 17:23:33 -0400655 rdev->mc.vram_width = numchan * chansize;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200656 /* Could aper size report 0 ? */
657 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
658 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000659 /* Setup GPU memory space */
660 rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
661 rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
Alex Deucher974b16e2009-09-25 10:06:39 -0400662
663 if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
664 rdev->mc.mc_vram_size = rdev->mc.aper_size;
665
666 if (rdev->mc.real_vram_size > rdev->mc.aper_size)
667 rdev->mc.real_vram_size = rdev->mc.aper_size;
668
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000669 if (rdev->flags & RADEON_IS_AGP) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000670 /* gtt_size is setup by radeon_agp_init */
671 rdev->mc.gtt_location = rdev->mc.agp_base;
672 tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size;
673 /* Try to put vram before or after AGP because we
674 * we want SYSTEM_APERTURE to cover both VRAM and
675 * AGP so that GPU can catch out of VRAM/AGP access
676 */
677 if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) {
678 /* Enought place before */
679 rdev->mc.vram_location = rdev->mc.gtt_location -
680 rdev->mc.mc_vram_size;
681 } else if (tmp > rdev->mc.mc_vram_size) {
682 /* Enought place after */
683 rdev->mc.vram_location = rdev->mc.gtt_location +
684 rdev->mc.gtt_size;
685 } else {
686 /* Try to setup VRAM then AGP might not
687 * not work on some card
688 */
689 rdev->mc.vram_location = 0x00000000UL;
690 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
691 }
692 } else {
Dave Airlie4d357ab2009-11-03 14:54:36 +1000693 rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
694 rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) &
695 0xFFFF) << 24;
696 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size;
697 if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
698 /* Enough place after vram */
699 rdev->mc.gtt_location = tmp;
700 } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) {
701 /* Enough place before vram */
702 rdev->mc.gtt_location = 0;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000703 } else {
Dave Airlie4d357ab2009-11-03 14:54:36 +1000704 /* Not enough place after or before shrink
705 * gart size
706 */
707 if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) {
708 rdev->mc.gtt_location = 0;
709 rdev->mc.gtt_size = rdev->mc.vram_location;
710 } else {
711 rdev->mc.gtt_location = tmp;
712 rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp;
713 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000714 }
Dave Airlie4d357ab2009-11-03 14:54:36 +1000715 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000716 }
717 rdev->mc.vram_start = rdev->mc.vram_location;
Jerome Glisse1a029b72009-10-06 19:04:30 +0200718 rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000719 rdev->mc.gtt_start = rdev->mc.gtt_location;
Jerome Glisse1a029b72009-10-06 19:04:30 +0200720 rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000721 /* FIXME: we should enforce default clock in case GPU is not in
722 * default setup
723 */
724 a.full = rfixed_const(100);
725 rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
726 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
Alex Deucher06b64762010-01-05 11:27:29 -0500727
728 if (rdev->flags & RADEON_IS_IGP)
729 rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
730
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000731 return 0;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200732}
733
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000734/* We doesn't check that the GPU really needs a reset we simply do the
735 * reset, it's up to the caller to determine if the GPU needs one. We
736 * might add an helper function to check that.
737 */
738int r600_gpu_soft_reset(struct radeon_device *rdev)
739{
Jerome Glissea3c19452009-10-01 18:02:13 +0200740 struct rv515_mc_save save;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000741 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
742 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
743 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
744 S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) |
745 S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) |
746 S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) |
747 S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) |
748 S_008010_GUI_ACTIVE(1);
749 u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) |
750 S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) |
751 S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) |
752 S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) |
753 S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) |
754 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
755 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
756 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
757 u32 srbm_reset = 0;
Jerome Glissea3c19452009-10-01 18:02:13 +0200758 u32 tmp;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000759
Jerome Glisse1a029b72009-10-06 19:04:30 +0200760 dev_info(rdev->dev, "GPU softreset \n");
761 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
762 RREG32(R_008010_GRBM_STATUS));
763 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
Jerome Glissea3c19452009-10-01 18:02:13 +0200764 RREG32(R_008014_GRBM_STATUS2));
Jerome Glisse1a029b72009-10-06 19:04:30 +0200765 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
766 RREG32(R_000E50_SRBM_STATUS));
Jerome Glissea3c19452009-10-01 18:02:13 +0200767 rv515_mc_stop(rdev, &save);
768 if (r600_mc_wait_for_idle(rdev)) {
769 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
770 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000771 /* Disable CP parsing/prefetching */
772 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
773 /* Check if any of the rendering block is busy and reset it */
774 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
775 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
Jerome Glissea3c19452009-10-01 18:02:13 +0200776 tmp = S_008020_SOFT_RESET_CR(1) |
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000777 S_008020_SOFT_RESET_DB(1) |
778 S_008020_SOFT_RESET_CB(1) |
779 S_008020_SOFT_RESET_PA(1) |
780 S_008020_SOFT_RESET_SC(1) |
781 S_008020_SOFT_RESET_SMX(1) |
782 S_008020_SOFT_RESET_SPI(1) |
783 S_008020_SOFT_RESET_SX(1) |
784 S_008020_SOFT_RESET_SH(1) |
785 S_008020_SOFT_RESET_TC(1) |
786 S_008020_SOFT_RESET_TA(1) |
787 S_008020_SOFT_RESET_VC(1) |
Jerome Glissea3c19452009-10-01 18:02:13 +0200788 S_008020_SOFT_RESET_VGT(1);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200789 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
Jerome Glissea3c19452009-10-01 18:02:13 +0200790 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000791 (void)RREG32(R_008020_GRBM_SOFT_RESET);
792 udelay(50);
793 WREG32(R_008020_GRBM_SOFT_RESET, 0);
794 (void)RREG32(R_008020_GRBM_SOFT_RESET);
795 }
796 /* Reset CP (we always reset CP) */
Jerome Glissea3c19452009-10-01 18:02:13 +0200797 tmp = S_008020_SOFT_RESET_CP(1);
798 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
799 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000800 (void)RREG32(R_008020_GRBM_SOFT_RESET);
801 udelay(50);
802 WREG32(R_008020_GRBM_SOFT_RESET, 0);
803 (void)RREG32(R_008020_GRBM_SOFT_RESET);
804 /* Reset others GPU block if necessary */
805 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
806 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
807 if (G_000E50_GRBM_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
808 srbm_reset |= S_000E60_SOFT_RESET_GRBM(1);
809 if (G_000E50_HI_RQ_PENDING(RREG32(R_000E50_SRBM_STATUS)))
810 srbm_reset |= S_000E60_SOFT_RESET_IH(1);
811 if (G_000E50_VMC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
812 srbm_reset |= S_000E60_SOFT_RESET_VMC(1);
813 if (G_000E50_MCB_BUSY(RREG32(R_000E50_SRBM_STATUS)))
814 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
815 if (G_000E50_MCDZ_BUSY(RREG32(R_000E50_SRBM_STATUS)))
816 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
817 if (G_000E50_MCDY_BUSY(RREG32(R_000E50_SRBM_STATUS)))
818 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
819 if (G_000E50_MCDX_BUSY(RREG32(R_000E50_SRBM_STATUS)))
820 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
821 if (G_000E50_MCDW_BUSY(RREG32(R_000E50_SRBM_STATUS)))
822 srbm_reset |= S_000E60_SOFT_RESET_MC(1);
823 if (G_000E50_RLC_BUSY(RREG32(R_000E50_SRBM_STATUS)))
824 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
825 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
826 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200827 if (G_000E50_BIF_BUSY(RREG32(R_000E50_SRBM_STATUS)))
828 srbm_reset |= S_000E60_SOFT_RESET_BIF(1);
829 dev_info(rdev->dev, " R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
830 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
831 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
832 udelay(50);
833 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
834 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000835 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
836 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
837 udelay(50);
838 WREG32(R_000E60_SRBM_SOFT_RESET, 0);
839 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
840 /* Wait a little for things to settle down */
841 udelay(50);
Jerome Glisse1a029b72009-10-06 19:04:30 +0200842 dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n",
843 RREG32(R_008010_GRBM_STATUS));
844 dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n",
845 RREG32(R_008014_GRBM_STATUS2));
846 dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n",
847 RREG32(R_000E50_SRBM_STATUS));
Jerome Glissea3c19452009-10-01 18:02:13 +0200848 /* After reset we need to reinit the asic as GPU often endup in an
849 * incoherent state.
850 */
851 atom_asic_init(rdev->mode_info.atom_context);
852 rv515_mc_resume(rdev, &save);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000853 return 0;
854}
855
856int r600_gpu_reset(struct radeon_device *rdev)
857{
858 return r600_gpu_soft_reset(rdev);
859}
860
861static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
862 u32 num_backends,
863 u32 backend_disable_mask)
864{
865 u32 backend_map = 0;
866 u32 enabled_backends_mask;
867 u32 enabled_backends_count;
868 u32 cur_pipe;
869 u32 swizzle_pipe[R6XX_MAX_PIPES];
870 u32 cur_backend;
871 u32 i;
872
873 if (num_tile_pipes > R6XX_MAX_PIPES)
874 num_tile_pipes = R6XX_MAX_PIPES;
875 if (num_tile_pipes < 1)
876 num_tile_pipes = 1;
877 if (num_backends > R6XX_MAX_BACKENDS)
878 num_backends = R6XX_MAX_BACKENDS;
879 if (num_backends < 1)
880 num_backends = 1;
881
882 enabled_backends_mask = 0;
883 enabled_backends_count = 0;
884 for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
885 if (((backend_disable_mask >> i) & 1) == 0) {
886 enabled_backends_mask |= (1 << i);
887 ++enabled_backends_count;
888 }
889 if (enabled_backends_count == num_backends)
890 break;
891 }
892
893 if (enabled_backends_count == 0) {
894 enabled_backends_mask = 1;
895 enabled_backends_count = 1;
896 }
897
898 if (enabled_backends_count != num_backends)
899 num_backends = enabled_backends_count;
900
901 memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
902 switch (num_tile_pipes) {
903 case 1:
904 swizzle_pipe[0] = 0;
905 break;
906 case 2:
907 swizzle_pipe[0] = 0;
908 swizzle_pipe[1] = 1;
909 break;
910 case 3:
911 swizzle_pipe[0] = 0;
912 swizzle_pipe[1] = 1;
913 swizzle_pipe[2] = 2;
914 break;
915 case 4:
916 swizzle_pipe[0] = 0;
917 swizzle_pipe[1] = 1;
918 swizzle_pipe[2] = 2;
919 swizzle_pipe[3] = 3;
920 break;
921 case 5:
922 swizzle_pipe[0] = 0;
923 swizzle_pipe[1] = 1;
924 swizzle_pipe[2] = 2;
925 swizzle_pipe[3] = 3;
926 swizzle_pipe[4] = 4;
927 break;
928 case 6:
929 swizzle_pipe[0] = 0;
930 swizzle_pipe[1] = 2;
931 swizzle_pipe[2] = 4;
932 swizzle_pipe[3] = 5;
933 swizzle_pipe[4] = 1;
934 swizzle_pipe[5] = 3;
935 break;
936 case 7:
937 swizzle_pipe[0] = 0;
938 swizzle_pipe[1] = 2;
939 swizzle_pipe[2] = 4;
940 swizzle_pipe[3] = 6;
941 swizzle_pipe[4] = 1;
942 swizzle_pipe[5] = 3;
943 swizzle_pipe[6] = 5;
944 break;
945 case 8:
946 swizzle_pipe[0] = 0;
947 swizzle_pipe[1] = 2;
948 swizzle_pipe[2] = 4;
949 swizzle_pipe[3] = 6;
950 swizzle_pipe[4] = 1;
951 swizzle_pipe[5] = 3;
952 swizzle_pipe[6] = 5;
953 swizzle_pipe[7] = 7;
954 break;
955 }
956
957 cur_backend = 0;
958 for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
959 while (((1 << cur_backend) & enabled_backends_mask) == 0)
960 cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
961
962 backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
963
964 cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
965 }
966
967 return backend_map;
968}
969
970int r600_count_pipe_bits(uint32_t val)
971{
972 int i, ret = 0;
973
974 for (i = 0; i < 32; i++) {
975 ret += val & 1;
976 val >>= 1;
977 }
978 return ret;
979}
980
981void r600_gpu_init(struct radeon_device *rdev)
982{
983 u32 tiling_config;
984 u32 ramcfg;
985 u32 tmp;
986 int i, j;
987 u32 sq_config;
988 u32 sq_gpr_resource_mgmt_1 = 0;
989 u32 sq_gpr_resource_mgmt_2 = 0;
990 u32 sq_thread_resource_mgmt = 0;
991 u32 sq_stack_resource_mgmt_1 = 0;
992 u32 sq_stack_resource_mgmt_2 = 0;
993
994 /* FIXME: implement */
995 switch (rdev->family) {
996 case CHIP_R600:
997 rdev->config.r600.max_pipes = 4;
998 rdev->config.r600.max_tile_pipes = 8;
999 rdev->config.r600.max_simds = 4;
1000 rdev->config.r600.max_backends = 4;
1001 rdev->config.r600.max_gprs = 256;
1002 rdev->config.r600.max_threads = 192;
1003 rdev->config.r600.max_stack_entries = 256;
1004 rdev->config.r600.max_hw_contexts = 8;
1005 rdev->config.r600.max_gs_threads = 16;
1006 rdev->config.r600.sx_max_export_size = 128;
1007 rdev->config.r600.sx_max_export_pos_size = 16;
1008 rdev->config.r600.sx_max_export_smx_size = 128;
1009 rdev->config.r600.sq_num_cf_insts = 2;
1010 break;
1011 case CHIP_RV630:
1012 case CHIP_RV635:
1013 rdev->config.r600.max_pipes = 2;
1014 rdev->config.r600.max_tile_pipes = 2;
1015 rdev->config.r600.max_simds = 3;
1016 rdev->config.r600.max_backends = 1;
1017 rdev->config.r600.max_gprs = 128;
1018 rdev->config.r600.max_threads = 192;
1019 rdev->config.r600.max_stack_entries = 128;
1020 rdev->config.r600.max_hw_contexts = 8;
1021 rdev->config.r600.max_gs_threads = 4;
1022 rdev->config.r600.sx_max_export_size = 128;
1023 rdev->config.r600.sx_max_export_pos_size = 16;
1024 rdev->config.r600.sx_max_export_smx_size = 128;
1025 rdev->config.r600.sq_num_cf_insts = 2;
1026 break;
1027 case CHIP_RV610:
1028 case CHIP_RV620:
1029 case CHIP_RS780:
1030 case CHIP_RS880:
1031 rdev->config.r600.max_pipes = 1;
1032 rdev->config.r600.max_tile_pipes = 1;
1033 rdev->config.r600.max_simds = 2;
1034 rdev->config.r600.max_backends = 1;
1035 rdev->config.r600.max_gprs = 128;
1036 rdev->config.r600.max_threads = 192;
1037 rdev->config.r600.max_stack_entries = 128;
1038 rdev->config.r600.max_hw_contexts = 4;
1039 rdev->config.r600.max_gs_threads = 4;
1040 rdev->config.r600.sx_max_export_size = 128;
1041 rdev->config.r600.sx_max_export_pos_size = 16;
1042 rdev->config.r600.sx_max_export_smx_size = 128;
1043 rdev->config.r600.sq_num_cf_insts = 1;
1044 break;
1045 case CHIP_RV670:
1046 rdev->config.r600.max_pipes = 4;
1047 rdev->config.r600.max_tile_pipes = 4;
1048 rdev->config.r600.max_simds = 4;
1049 rdev->config.r600.max_backends = 4;
1050 rdev->config.r600.max_gprs = 192;
1051 rdev->config.r600.max_threads = 192;
1052 rdev->config.r600.max_stack_entries = 256;
1053 rdev->config.r600.max_hw_contexts = 8;
1054 rdev->config.r600.max_gs_threads = 16;
1055 rdev->config.r600.sx_max_export_size = 128;
1056 rdev->config.r600.sx_max_export_pos_size = 16;
1057 rdev->config.r600.sx_max_export_smx_size = 128;
1058 rdev->config.r600.sq_num_cf_insts = 2;
1059 break;
1060 default:
1061 break;
1062 }
1063
1064 /* Initialize HDP */
1065 for (i = 0, j = 0; i < 32; i++, j += 0x18) {
1066 WREG32((0x2c14 + j), 0x00000000);
1067 WREG32((0x2c18 + j), 0x00000000);
1068 WREG32((0x2c1c + j), 0x00000000);
1069 WREG32((0x2c20 + j), 0x00000000);
1070 WREG32((0x2c24 + j), 0x00000000);
1071 }
1072
1073 WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
1074
1075 /* Setup tiling */
1076 tiling_config = 0;
1077 ramcfg = RREG32(RAMCFG);
1078 switch (rdev->config.r600.max_tile_pipes) {
1079 case 1:
1080 tiling_config |= PIPE_TILING(0);
Jerome Glisse961fb592010-02-10 22:30:05 +00001081 rdev->config.r600.tiling_npipes = 1;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001082 break;
1083 case 2:
1084 tiling_config |= PIPE_TILING(1);
Jerome Glisse961fb592010-02-10 22:30:05 +00001085 rdev->config.r600.tiling_npipes = 2;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001086 break;
1087 case 4:
1088 tiling_config |= PIPE_TILING(2);
Jerome Glisse961fb592010-02-10 22:30:05 +00001089 rdev->config.r600.tiling_npipes = 4;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001090 break;
1091 case 8:
1092 tiling_config |= PIPE_TILING(3);
Jerome Glisse961fb592010-02-10 22:30:05 +00001093 rdev->config.r600.tiling_npipes = 8;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001094 break;
1095 default:
1096 break;
1097 }
Jerome Glisse961fb592010-02-10 22:30:05 +00001098 rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001099 tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
1100 tiling_config |= GROUP_SIZE(0);
Jerome Glisse961fb592010-02-10 22:30:05 +00001101 rdev->config.r600.tiling_group_size = 256;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001102 tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
1103 if (tmp > 3) {
1104 tiling_config |= ROW_TILING(3);
1105 tiling_config |= SAMPLE_SPLIT(3);
1106 } else {
1107 tiling_config |= ROW_TILING(tmp);
1108 tiling_config |= SAMPLE_SPLIT(tmp);
1109 }
1110 tiling_config |= BANK_SWAPS(1);
1111 tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes,
1112 rdev->config.r600.max_backends,
1113 (0xff << rdev->config.r600.max_backends) & 0xff);
1114 tiling_config |= BACKEND_MAP(tmp);
1115 WREG32(GB_TILING_CONFIG, tiling_config);
1116 WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
1117 WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
1118
1119 tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK);
1120 WREG32(CC_RB_BACKEND_DISABLE, tmp);
1121
1122 /* Setup pipes */
1123 tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK);
1124 tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK);
1125 WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp);
1126 WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp);
1127
1128 tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK);
1129 WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
1130 WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK);
1131
1132 /* Setup some CP states */
1133 WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b)));
1134 WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40)));
1135
1136 WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT |
1137 SYNC_WALKER | SYNC_ALIGNER));
1138 /* Setup various GPU states */
1139 if (rdev->family == CHIP_RV670)
1140 WREG32(ARB_GDEC_RD_CNTL, 0x00000021);
1141
1142 tmp = RREG32(SX_DEBUG_1);
1143 tmp |= SMX_EVENT_RELEASE;
1144 if ((rdev->family > CHIP_R600))
1145 tmp |= ENABLE_NEW_SMX_ADDRESS;
1146 WREG32(SX_DEBUG_1, tmp);
1147
1148 if (((rdev->family) == CHIP_R600) ||
1149 ((rdev->family) == CHIP_RV630) ||
1150 ((rdev->family) == CHIP_RV610) ||
1151 ((rdev->family) == CHIP_RV620) ||
Alex Deucheree59f2b2009-11-05 13:11:46 -05001152 ((rdev->family) == CHIP_RS780) ||
1153 ((rdev->family) == CHIP_RS880)) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001154 WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
1155 } else {
1156 WREG32(DB_DEBUG, 0);
1157 }
1158 WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) |
1159 DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4)));
1160
1161 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1162 WREG32(VGT_NUM_INSTANCES, 0);
1163
1164 WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
1165 WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0));
1166
1167 tmp = RREG32(SQ_MS_FIFO_SIZES);
1168 if (((rdev->family) == CHIP_RV610) ||
1169 ((rdev->family) == CHIP_RV620) ||
Alex Deucheree59f2b2009-11-05 13:11:46 -05001170 ((rdev->family) == CHIP_RS780) ||
1171 ((rdev->family) == CHIP_RS880)) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001172 tmp = (CACHE_FIFO_SIZE(0xa) |
1173 FETCH_FIFO_HIWATER(0xa) |
1174 DONE_FIFO_HIWATER(0xe0) |
1175 ALU_UPDATE_FIFO_HIWATER(0x8));
1176 } else if (((rdev->family) == CHIP_R600) ||
1177 ((rdev->family) == CHIP_RV630)) {
1178 tmp &= ~DONE_FIFO_HIWATER(0xff);
1179 tmp |= DONE_FIFO_HIWATER(0x4);
1180 }
1181 WREG32(SQ_MS_FIFO_SIZES, tmp);
1182
1183 /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
1184 * should be adjusted as needed by the 2D/3D drivers. This just sets default values
1185 */
1186 sq_config = RREG32(SQ_CONFIG);
1187 sq_config &= ~(PS_PRIO(3) |
1188 VS_PRIO(3) |
1189 GS_PRIO(3) |
1190 ES_PRIO(3));
1191 sq_config |= (DX9_CONSTS |
1192 VC_ENABLE |
1193 PS_PRIO(0) |
1194 VS_PRIO(1) |
1195 GS_PRIO(2) |
1196 ES_PRIO(3));
1197
1198 if ((rdev->family) == CHIP_R600) {
1199 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) |
1200 NUM_VS_GPRS(124) |
1201 NUM_CLAUSE_TEMP_GPRS(4));
1202 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) |
1203 NUM_ES_GPRS(0));
1204 sq_thread_resource_mgmt = (NUM_PS_THREADS(136) |
1205 NUM_VS_THREADS(48) |
1206 NUM_GS_THREADS(4) |
1207 NUM_ES_THREADS(4));
1208 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) |
1209 NUM_VS_STACK_ENTRIES(128));
1210 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) |
1211 NUM_ES_STACK_ENTRIES(0));
1212 } else if (((rdev->family) == CHIP_RV610) ||
1213 ((rdev->family) == CHIP_RV620) ||
Alex Deucheree59f2b2009-11-05 13:11:46 -05001214 ((rdev->family) == CHIP_RS780) ||
1215 ((rdev->family) == CHIP_RS880)) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001216 /* no vertex cache */
1217 sq_config &= ~VC_ENABLE;
1218
1219 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
1220 NUM_VS_GPRS(44) |
1221 NUM_CLAUSE_TEMP_GPRS(2));
1222 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
1223 NUM_ES_GPRS(17));
1224 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
1225 NUM_VS_THREADS(78) |
1226 NUM_GS_THREADS(4) |
1227 NUM_ES_THREADS(31));
1228 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
1229 NUM_VS_STACK_ENTRIES(40));
1230 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
1231 NUM_ES_STACK_ENTRIES(16));
1232 } else if (((rdev->family) == CHIP_RV630) ||
1233 ((rdev->family) == CHIP_RV635)) {
1234 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
1235 NUM_VS_GPRS(44) |
1236 NUM_CLAUSE_TEMP_GPRS(2));
1237 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) |
1238 NUM_ES_GPRS(18));
1239 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
1240 NUM_VS_THREADS(78) |
1241 NUM_GS_THREADS(4) |
1242 NUM_ES_THREADS(31));
1243 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
1244 NUM_VS_STACK_ENTRIES(40));
1245 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
1246 NUM_ES_STACK_ENTRIES(16));
1247 } else if ((rdev->family) == CHIP_RV670) {
1248 sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
1249 NUM_VS_GPRS(44) |
1250 NUM_CLAUSE_TEMP_GPRS(2));
1251 sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
1252 NUM_ES_GPRS(17));
1253 sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
1254 NUM_VS_THREADS(78) |
1255 NUM_GS_THREADS(4) |
1256 NUM_ES_THREADS(31));
1257 sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) |
1258 NUM_VS_STACK_ENTRIES(64));
1259 sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) |
1260 NUM_ES_STACK_ENTRIES(64));
1261 }
1262
1263 WREG32(SQ_CONFIG, sq_config);
1264 WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
1265 WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
1266 WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
1267 WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
1268 WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
1269
1270 if (((rdev->family) == CHIP_RV610) ||
1271 ((rdev->family) == CHIP_RV620) ||
Alex Deucheree59f2b2009-11-05 13:11:46 -05001272 ((rdev->family) == CHIP_RS780) ||
1273 ((rdev->family) == CHIP_RS880)) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001274 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
1275 } else {
1276 WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
1277 }
1278
1279 /* More default values. 2D/3D driver should adjust as needed */
1280 WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) |
1281 S1_X(0x4) | S1_Y(0xc)));
1282 WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) |
1283 S1_X(0x2) | S1_Y(0x2) |
1284 S2_X(0xa) | S2_Y(0x6) |
1285 S3_X(0x6) | S3_Y(0xa)));
1286 WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) |
1287 S1_X(0x4) | S1_Y(0xc) |
1288 S2_X(0x1) | S2_Y(0x6) |
1289 S3_X(0xa) | S3_Y(0xe)));
1290 WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) |
1291 S5_X(0x0) | S5_Y(0x0) |
1292 S6_X(0xb) | S6_Y(0x4) |
1293 S7_X(0x7) | S7_Y(0x8)));
1294
1295 WREG32(VGT_STRMOUT_EN, 0);
1296 tmp = rdev->config.r600.max_pipes * 16;
1297 switch (rdev->family) {
1298 case CHIP_RV610:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001299 case CHIP_RV620:
Alex Deucheree59f2b2009-11-05 13:11:46 -05001300 case CHIP_RS780:
1301 case CHIP_RS880:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001302 tmp += 32;
1303 break;
1304 case CHIP_RV670:
1305 tmp += 128;
1306 break;
1307 default:
1308 break;
1309 }
1310 if (tmp > 256) {
1311 tmp = 256;
1312 }
1313 WREG32(VGT_ES_PER_GS, 128);
1314 WREG32(VGT_GS_PER_ES, tmp);
1315 WREG32(VGT_GS_PER_VS, 2);
1316 WREG32(VGT_GS_VERTEX_REUSE, 16);
1317
1318 /* more default values. 2D/3D driver should adjust as needed */
1319 WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
1320 WREG32(VGT_STRMOUT_EN, 0);
1321 WREG32(SX_MISC, 0);
1322 WREG32(PA_SC_MODE_CNTL, 0);
1323 WREG32(PA_SC_AA_CONFIG, 0);
1324 WREG32(PA_SC_LINE_STIPPLE, 0);
1325 WREG32(SPI_INPUT_Z, 0);
1326 WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
1327 WREG32(CB_COLOR7_FRAG, 0);
1328
1329 /* Clear render buffer base addresses */
1330 WREG32(CB_COLOR0_BASE, 0);
1331 WREG32(CB_COLOR1_BASE, 0);
1332 WREG32(CB_COLOR2_BASE, 0);
1333 WREG32(CB_COLOR3_BASE, 0);
1334 WREG32(CB_COLOR4_BASE, 0);
1335 WREG32(CB_COLOR5_BASE, 0);
1336 WREG32(CB_COLOR6_BASE, 0);
1337 WREG32(CB_COLOR7_BASE, 0);
1338 WREG32(CB_COLOR7_FRAG, 0);
1339
1340 switch (rdev->family) {
1341 case CHIP_RV610:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001342 case CHIP_RV620:
Alex Deucheree59f2b2009-11-05 13:11:46 -05001343 case CHIP_RS780:
1344 case CHIP_RS880:
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001345 tmp = TC_L2_SIZE(8);
1346 break;
1347 case CHIP_RV630:
1348 case CHIP_RV635:
1349 tmp = TC_L2_SIZE(4);
1350 break;
1351 case CHIP_R600:
1352 tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT;
1353 break;
1354 default:
1355 tmp = TC_L2_SIZE(0);
1356 break;
1357 }
1358 WREG32(TC_CNTL, tmp);
1359
1360 tmp = RREG32(HDP_HOST_PATH_CNTL);
1361 WREG32(HDP_HOST_PATH_CNTL, tmp);
1362
1363 tmp = RREG32(ARB_POP);
1364 tmp |= ENABLE_TC128;
1365 WREG32(ARB_POP, tmp);
1366
1367 WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
1368 WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
1369 NUM_CLIP_SEQ(3)));
1370 WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095));
1371}
1372
1373
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001374/*
1375 * Indirect registers accessor
1376 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001377u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001378{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001379 u32 r;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001380
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001381 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
1382 (void)RREG32(PCIE_PORT_INDEX);
1383 r = RREG32(PCIE_PORT_DATA);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001384 return r;
1385}
1386
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001387void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001388{
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001389 WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
1390 (void)RREG32(PCIE_PORT_INDEX);
1391 WREG32(PCIE_PORT_DATA, (v));
1392 (void)RREG32(PCIE_PORT_DATA);
1393}
1394
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001395/*
1396 * CP & Ring
1397 */
1398void r600_cp_stop(struct radeon_device *rdev)
1399{
1400 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1401}
1402
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001403int r600_init_microcode(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001404{
1405 struct platform_device *pdev;
1406 const char *chip_name;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001407 const char *rlc_chip_name;
1408 size_t pfp_req_size, me_req_size, rlc_req_size;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001409 char fw_name[30];
1410 int err;
1411
1412 DRM_DEBUG("\n");
1413
1414 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
1415 err = IS_ERR(pdev);
1416 if (err) {
1417 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
1418 return -EINVAL;
1419 }
1420
1421 switch (rdev->family) {
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001422 case CHIP_R600:
1423 chip_name = "R600";
1424 rlc_chip_name = "R600";
1425 break;
1426 case CHIP_RV610:
1427 chip_name = "RV610";
1428 rlc_chip_name = "R600";
1429 break;
1430 case CHIP_RV630:
1431 chip_name = "RV630";
1432 rlc_chip_name = "R600";
1433 break;
1434 case CHIP_RV620:
1435 chip_name = "RV620";
1436 rlc_chip_name = "R600";
1437 break;
1438 case CHIP_RV635:
1439 chip_name = "RV635";
1440 rlc_chip_name = "R600";
1441 break;
1442 case CHIP_RV670:
1443 chip_name = "RV670";
1444 rlc_chip_name = "R600";
1445 break;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001446 case CHIP_RS780:
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001447 case CHIP_RS880:
1448 chip_name = "RS780";
1449 rlc_chip_name = "R600";
1450 break;
1451 case CHIP_RV770:
1452 chip_name = "RV770";
1453 rlc_chip_name = "R700";
1454 break;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001455 case CHIP_RV730:
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001456 case CHIP_RV740:
1457 chip_name = "RV730";
1458 rlc_chip_name = "R700";
1459 break;
1460 case CHIP_RV710:
1461 chip_name = "RV710";
1462 rlc_chip_name = "R700";
1463 break;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001464 default: BUG();
1465 }
1466
1467 if (rdev->family >= CHIP_RV770) {
1468 pfp_req_size = R700_PFP_UCODE_SIZE * 4;
1469 me_req_size = R700_PM4_UCODE_SIZE * 4;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001470 rlc_req_size = R700_RLC_UCODE_SIZE * 4;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001471 } else {
1472 pfp_req_size = PFP_UCODE_SIZE * 4;
1473 me_req_size = PM4_UCODE_SIZE * 12;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001474 rlc_req_size = RLC_UCODE_SIZE * 4;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001475 }
1476
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001477 DRM_INFO("Loading %s Microcode\n", chip_name);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001478
1479 snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
1480 err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
1481 if (err)
1482 goto out;
1483 if (rdev->pfp_fw->size != pfp_req_size) {
1484 printk(KERN_ERR
1485 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
1486 rdev->pfp_fw->size, fw_name);
1487 err = -EINVAL;
1488 goto out;
1489 }
1490
1491 snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
1492 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
1493 if (err)
1494 goto out;
1495 if (rdev->me_fw->size != me_req_size) {
1496 printk(KERN_ERR
1497 "r600_cp: Bogus length %zu in firmware \"%s\"\n",
1498 rdev->me_fw->size, fw_name);
1499 err = -EINVAL;
1500 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001501
1502 snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
1503 err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
1504 if (err)
1505 goto out;
1506 if (rdev->rlc_fw->size != rlc_req_size) {
1507 printk(KERN_ERR
1508 "r600_rlc: Bogus length %zu in firmware \"%s\"\n",
1509 rdev->rlc_fw->size, fw_name);
1510 err = -EINVAL;
1511 }
1512
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001513out:
1514 platform_device_unregister(pdev);
1515
1516 if (err) {
1517 if (err != -EINVAL)
1518 printk(KERN_ERR
1519 "r600_cp: Failed to load firmware \"%s\"\n",
1520 fw_name);
1521 release_firmware(rdev->pfp_fw);
1522 rdev->pfp_fw = NULL;
1523 release_firmware(rdev->me_fw);
1524 rdev->me_fw = NULL;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001525 release_firmware(rdev->rlc_fw);
1526 rdev->rlc_fw = NULL;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001527 }
1528 return err;
1529}
1530
1531static int r600_cp_load_microcode(struct radeon_device *rdev)
1532{
1533 const __be32 *fw_data;
1534 int i;
1535
1536 if (!rdev->me_fw || !rdev->pfp_fw)
1537 return -EINVAL;
1538
1539 r600_cp_stop(rdev);
1540
1541 WREG32(CP_RB_CNTL, RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
1542
1543 /* Reset cp */
1544 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1545 RREG32(GRBM_SOFT_RESET);
1546 mdelay(15);
1547 WREG32(GRBM_SOFT_RESET, 0);
1548
1549 WREG32(CP_ME_RAM_WADDR, 0);
1550
1551 fw_data = (const __be32 *)rdev->me_fw->data;
1552 WREG32(CP_ME_RAM_WADDR, 0);
1553 for (i = 0; i < PM4_UCODE_SIZE * 3; i++)
1554 WREG32(CP_ME_RAM_DATA,
1555 be32_to_cpup(fw_data++));
1556
1557 fw_data = (const __be32 *)rdev->pfp_fw->data;
1558 WREG32(CP_PFP_UCODE_ADDR, 0);
1559 for (i = 0; i < PFP_UCODE_SIZE; i++)
1560 WREG32(CP_PFP_UCODE_DATA,
1561 be32_to_cpup(fw_data++));
1562
1563 WREG32(CP_PFP_UCODE_ADDR, 0);
1564 WREG32(CP_ME_RAM_WADDR, 0);
1565 WREG32(CP_ME_RAM_RADDR, 0);
1566 return 0;
1567}
1568
1569int r600_cp_start(struct radeon_device *rdev)
1570{
1571 int r;
1572 uint32_t cp_me;
1573
1574 r = radeon_ring_lock(rdev, 7);
1575 if (r) {
1576 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1577 return r;
1578 }
1579 radeon_ring_write(rdev, PACKET3(PACKET3_ME_INITIALIZE, 5));
1580 radeon_ring_write(rdev, 0x1);
1581 if (rdev->family < CHIP_RV770) {
1582 radeon_ring_write(rdev, 0x3);
1583 radeon_ring_write(rdev, rdev->config.r600.max_hw_contexts - 1);
1584 } else {
1585 radeon_ring_write(rdev, 0x0);
1586 radeon_ring_write(rdev, rdev->config.rv770.max_hw_contexts - 1);
1587 }
1588 radeon_ring_write(rdev, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
1589 radeon_ring_write(rdev, 0);
1590 radeon_ring_write(rdev, 0);
1591 radeon_ring_unlock_commit(rdev);
1592
1593 cp_me = 0xff;
1594 WREG32(R_0086D8_CP_ME_CNTL, cp_me);
1595 return 0;
1596}
1597
1598int r600_cp_resume(struct radeon_device *rdev)
1599{
1600 u32 tmp;
1601 u32 rb_bufsz;
1602 int r;
1603
1604 /* Reset cp */
1605 WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
1606 RREG32(GRBM_SOFT_RESET);
1607 mdelay(15);
1608 WREG32(GRBM_SOFT_RESET, 0);
1609
1610 /* Set ring buffer size */
1611 rb_bufsz = drm_order(rdev->cp.ring_size / 8);
Alex Deucherd6f28932009-11-02 16:01:27 -05001612 tmp = RB_NO_UPDATE | (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001613#ifdef __BIG_ENDIAN
Alex Deucherd6f28932009-11-02 16:01:27 -05001614 tmp |= BUF_SWAP_32BIT;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001615#endif
Alex Deucherd6f28932009-11-02 16:01:27 -05001616 WREG32(CP_RB_CNTL, tmp);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001617 WREG32(CP_SEM_WAIT_TIMER, 0x4);
1618
1619 /* Set the write pointer delay */
1620 WREG32(CP_RB_WPTR_DELAY, 0);
1621
1622 /* Initialize the ring buffer's read and write pointers */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001623 WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
1624 WREG32(CP_RB_RPTR_WR, 0);
1625 WREG32(CP_RB_WPTR, 0);
1626 WREG32(CP_RB_RPTR_ADDR, rdev->cp.gpu_addr & 0xFFFFFFFF);
1627 WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->cp.gpu_addr));
1628 mdelay(1);
1629 WREG32(CP_RB_CNTL, tmp);
1630
1631 WREG32(CP_RB_BASE, rdev->cp.gpu_addr >> 8);
1632 WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
1633
1634 rdev->cp.rptr = RREG32(CP_RB_RPTR);
1635 rdev->cp.wptr = RREG32(CP_RB_WPTR);
1636
1637 r600_cp_start(rdev);
1638 rdev->cp.ready = true;
1639 r = radeon_ring_test(rdev);
1640 if (r) {
1641 rdev->cp.ready = false;
1642 return r;
1643 }
1644 return 0;
1645}
1646
1647void r600_cp_commit(struct radeon_device *rdev)
1648{
1649 WREG32(CP_RB_WPTR, rdev->cp.wptr);
1650 (void)RREG32(CP_RB_WPTR);
1651}
1652
1653void r600_ring_init(struct radeon_device *rdev, unsigned ring_size)
1654{
1655 u32 rb_bufsz;
1656
1657 /* Align ring size */
1658 rb_bufsz = drm_order(ring_size / 8);
1659 ring_size = (1 << (rb_bufsz + 1)) * 4;
1660 rdev->cp.ring_size = ring_size;
1661 rdev->cp.align_mask = 16 - 1;
1662}
1663
Jerome Glisse655efd32010-02-02 11:51:45 +01001664void r600_cp_fini(struct radeon_device *rdev)
1665{
1666 r600_cp_stop(rdev);
1667 radeon_ring_fini(rdev);
1668}
1669
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001670
1671/*
1672 * GPU scratch registers helpers function.
1673 */
1674void r600_scratch_init(struct radeon_device *rdev)
1675{
1676 int i;
1677
1678 rdev->scratch.num_reg = 7;
1679 for (i = 0; i < rdev->scratch.num_reg; i++) {
1680 rdev->scratch.free[i] = true;
1681 rdev->scratch.reg[i] = SCRATCH_REG0 + (i * 4);
1682 }
1683}
1684
1685int r600_ring_test(struct radeon_device *rdev)
1686{
1687 uint32_t scratch;
1688 uint32_t tmp = 0;
1689 unsigned i;
1690 int r;
1691
1692 r = radeon_scratch_get(rdev, &scratch);
1693 if (r) {
1694 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
1695 return r;
1696 }
1697 WREG32(scratch, 0xCAFEDEAD);
1698 r = radeon_ring_lock(rdev, 3);
1699 if (r) {
1700 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
1701 radeon_scratch_free(rdev, scratch);
1702 return r;
1703 }
1704 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1705 radeon_ring_write(rdev, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
1706 radeon_ring_write(rdev, 0xDEADBEEF);
1707 radeon_ring_unlock_commit(rdev);
1708 for (i = 0; i < rdev->usec_timeout; i++) {
1709 tmp = RREG32(scratch);
1710 if (tmp == 0xDEADBEEF)
1711 break;
1712 DRM_UDELAY(1);
1713 }
1714 if (i < rdev->usec_timeout) {
1715 DRM_INFO("ring test succeeded in %d usecs\n", i);
1716 } else {
1717 DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n",
1718 scratch, tmp);
1719 r = -EINVAL;
1720 }
1721 radeon_scratch_free(rdev, scratch);
1722 return r;
1723}
1724
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001725void r600_wb_disable(struct radeon_device *rdev)
1726{
Jerome Glisse4c788672009-11-20 14:29:23 +01001727 int r;
1728
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001729 WREG32(SCRATCH_UMSK, 0);
1730 if (rdev->wb.wb_obj) {
Jerome Glisse4c788672009-11-20 14:29:23 +01001731 r = radeon_bo_reserve(rdev->wb.wb_obj, false);
1732 if (unlikely(r != 0))
1733 return;
1734 radeon_bo_kunmap(rdev->wb.wb_obj);
1735 radeon_bo_unpin(rdev->wb.wb_obj);
1736 radeon_bo_unreserve(rdev->wb.wb_obj);
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001737 }
1738}
1739
1740void r600_wb_fini(struct radeon_device *rdev)
1741{
1742 r600_wb_disable(rdev);
1743 if (rdev->wb.wb_obj) {
Jerome Glisse4c788672009-11-20 14:29:23 +01001744 radeon_bo_unref(&rdev->wb.wb_obj);
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001745 rdev->wb.wb = NULL;
1746 rdev->wb.wb_obj = NULL;
1747 }
1748}
1749
1750int r600_wb_enable(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001751{
1752 int r;
1753
1754 if (rdev->wb.wb_obj == NULL) {
Jerome Glisse4c788672009-11-20 14:29:23 +01001755 r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
1756 RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001757 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +01001758 dev_warn(rdev->dev, "(%d) create WB bo failed\n", r);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001759 return r;
1760 }
Jerome Glisse4c788672009-11-20 14:29:23 +01001761 r = radeon_bo_reserve(rdev->wb.wb_obj, false);
1762 if (unlikely(r != 0)) {
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001763 r600_wb_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001764 return r;
1765 }
Jerome Glisse4c788672009-11-20 14:29:23 +01001766 r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
1767 &rdev->wb.gpu_addr);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001768 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +01001769 radeon_bo_unreserve(rdev->wb.wb_obj);
1770 dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r);
1771 r600_wb_fini(rdev);
1772 return r;
1773 }
1774 r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
1775 radeon_bo_unreserve(rdev->wb.wb_obj);
1776 if (r) {
1777 dev_warn(rdev->dev, "(%d) map WB bo failed\n", r);
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001778 r600_wb_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001779 return r;
1780 }
1781 }
1782 WREG32(SCRATCH_ADDR, (rdev->wb.gpu_addr >> 8) & 0xFFFFFFFF);
1783 WREG32(CP_RB_RPTR_ADDR, (rdev->wb.gpu_addr + 1024) & 0xFFFFFFFC);
1784 WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + 1024) & 0xFF);
1785 WREG32(SCRATCH_UMSK, 0xff);
1786 return 0;
1787}
1788
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001789void r600_fence_ring_emit(struct radeon_device *rdev,
1790 struct radeon_fence *fence)
1791{
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001792 /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */
Alex Deucher44224c32010-02-04 11:01:52 -05001793
1794 radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0));
1795 radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT);
1796 /* wait for 3D idle clean */
1797 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1798 radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
1799 radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001800 /* Emit fence sequence & fire IRQ */
1801 radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
1802 radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
1803 radeon_ring_write(rdev, fence->seq);
Jerome Glissecafe6602010-01-07 12:39:21 +01001804 radeon_ring_write(rdev, PACKET0(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0));
1805 radeon_ring_write(rdev, 1);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001806 /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
1807 radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0));
1808 radeon_ring_write(rdev, RB_INT_STAT);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001809}
1810
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001811int r600_copy_blit(struct radeon_device *rdev,
1812 uint64_t src_offset, uint64_t dst_offset,
1813 unsigned num_pages, struct radeon_fence *fence)
1814{
Jerome Glisseff82f052010-01-22 15:19:00 +01001815 int r;
1816
1817 mutex_lock(&rdev->r600_blit.mutex);
1818 rdev->r600_blit.vb_ib = NULL;
1819 r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE);
1820 if (r) {
1821 if (rdev->r600_blit.vb_ib)
1822 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
1823 mutex_unlock(&rdev->r600_blit.mutex);
1824 return r;
1825 }
Matt Turnera77f1712009-10-14 00:34:41 -04001826 r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001827 r600_blit_done_copy(rdev, fence);
Jerome Glisseff82f052010-01-22 15:19:00 +01001828 mutex_unlock(&rdev->r600_blit.mutex);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001829 return 0;
1830}
1831
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001832int r600_set_surface_reg(struct radeon_device *rdev, int reg,
1833 uint32_t tiling_flags, uint32_t pitch,
1834 uint32_t offset, uint32_t obj_size)
1835{
1836 /* FIXME: implement */
1837 return 0;
1838}
1839
1840void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
1841{
1842 /* FIXME: implement */
1843}
1844
1845
1846bool r600_card_posted(struct radeon_device *rdev)
1847{
1848 uint32_t reg;
1849
1850 /* first check CRTCs */
1851 reg = RREG32(D1CRTC_CONTROL) |
1852 RREG32(D2CRTC_CONTROL);
1853 if (reg & CRTC_EN)
1854 return true;
1855
1856 /* then check MEM_SIZE, in case the crtcs are off */
1857 if (RREG32(CONFIG_MEMSIZE))
1858 return true;
1859
1860 return false;
1861}
1862
Dave Airliefc30b8e2009-09-18 15:19:37 +10001863int r600_startup(struct radeon_device *rdev)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001864{
1865 int r;
1866
Alex Deucher779720a2009-12-09 19:31:44 -05001867 if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
1868 r = r600_init_microcode(rdev);
1869 if (r) {
1870 DRM_ERROR("Failed to load firmware!\n");
1871 return r;
1872 }
1873 }
1874
Jerome Glissea3c19452009-10-01 18:02:13 +02001875 r600_mc_program(rdev);
Jerome Glisse1a029b72009-10-06 19:04:30 +02001876 if (rdev->flags & RADEON_IS_AGP) {
1877 r600_agp_enable(rdev);
1878 } else {
1879 r = r600_pcie_gart_enable(rdev);
1880 if (r)
1881 return r;
1882 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001883 r600_gpu_init(rdev);
Jerome Glissec38c7b62010-02-04 17:27:27 +01001884 r = r600_blit_init(rdev);
1885 if (r) {
1886 r600_blit_fini(rdev);
1887 rdev->asic->copy = NULL;
1888 dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
1889 }
Jerome Glisseff82f052010-01-22 15:19:00 +01001890 /* pin copy shader into vram */
1891 if (rdev->r600_blit.shader_obj) {
1892 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
1893 if (unlikely(r != 0))
1894 return r;
1895 r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM,
1896 &rdev->r600_blit.shader_gpu_addr);
1897 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
Alex Deucher7923c612009-12-15 17:15:07 -05001898 if (r) {
Jerome Glisseff82f052010-01-22 15:19:00 +01001899 dev_err(rdev->dev, "(%d) pin blit object failed\n", r);
Alex Deucher7923c612009-12-15 17:15:07 -05001900 return r;
1901 }
1902 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001903 /* Enable IRQ */
Alex Deucherd8f60cf2009-12-01 13:43:46 -05001904 r = r600_irq_init(rdev);
1905 if (r) {
1906 DRM_ERROR("radeon: IH init failed (%d).\n", r);
1907 radeon_irq_kms_fini(rdev);
1908 return r;
1909 }
1910 r600_irq_set(rdev);
1911
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001912 r = radeon_ring_init(rdev, rdev->cp.ring_size);
1913 if (r)
1914 return r;
1915 r = r600_cp_load_microcode(rdev);
1916 if (r)
1917 return r;
1918 r = r600_cp_resume(rdev);
1919 if (r)
1920 return r;
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001921 /* write back buffer are not vital so don't worry about failure */
1922 r600_wb_enable(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001923 return 0;
1924}
1925
Dave Airlie28d52042009-09-21 14:33:58 +10001926void r600_vga_set_state(struct radeon_device *rdev, bool state)
1927{
1928 uint32_t temp;
1929
1930 temp = RREG32(CONFIG_CNTL);
1931 if (state == false) {
1932 temp &= ~(1<<0);
1933 temp |= (1<<1);
1934 } else {
1935 temp &= ~(1<<1);
1936 }
1937 WREG32(CONFIG_CNTL, temp);
1938}
1939
Dave Airliefc30b8e2009-09-18 15:19:37 +10001940int r600_resume(struct radeon_device *rdev)
1941{
1942 int r;
1943
Jerome Glisse1a029b72009-10-06 19:04:30 +02001944 /* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
1945 * posting will perform necessary task to bring back GPU into good
1946 * shape.
1947 */
Dave Airliefc30b8e2009-09-18 15:19:37 +10001948 /* post card */
Jerome Glissee7d40b92009-10-01 18:02:15 +02001949 atom_asic_init(rdev->mode_info.atom_context);
Dave Airliefc30b8e2009-09-18 15:19:37 +10001950 /* Initialize clocks */
1951 r = radeon_clocks_init(rdev);
1952 if (r) {
1953 return r;
1954 }
1955
1956 r = r600_startup(rdev);
1957 if (r) {
1958 DRM_ERROR("r600 startup failed on resume\n");
1959 return r;
1960 }
1961
Jerome Glisse62a8ea32009-10-01 18:02:11 +02001962 r = r600_ib_test(rdev);
Dave Airliefc30b8e2009-09-18 15:19:37 +10001963 if (r) {
1964 DRM_ERROR("radeon: failled testing IB (%d).\n", r);
1965 return r;
1966 }
1967 return r;
1968}
1969
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001970int r600_suspend(struct radeon_device *rdev)
1971{
Jerome Glisse4c788672009-11-20 14:29:23 +01001972 int r;
1973
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001974 /* FIXME: we should wait for ring to be empty */
1975 r600_cp_stop(rdev);
Dave Airliebc1a6312009-09-15 11:07:52 +10001976 rdev->cp.ready = false;
Jerome Glisse0c452492010-01-15 14:44:37 +01001977 r600_irq_suspend(rdev);
Jerome Glisse81cc35b2009-10-01 18:02:12 +02001978 r600_wb_disable(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02001979 r600_pcie_gart_disable(rdev);
Dave Airliebc1a6312009-09-15 11:07:52 +10001980 /* unpin shaders bo */
Jerome Glisse30d2d9a2010-01-13 10:29:27 +01001981 if (rdev->r600_blit.shader_obj) {
1982 r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
1983 if (!r) {
1984 radeon_bo_unpin(rdev->r600_blit.shader_obj);
1985 radeon_bo_unreserve(rdev->r600_blit.shader_obj);
1986 }
1987 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10001988 return 0;
1989}
1990
1991/* Plan is to move initialization in that function and use
1992 * helper function so that radeon_device_init pretty much
1993 * do nothing more than calling asic specific function. This
1994 * should also allow to remove a bunch of callback function
1995 * like vram_info.
1996 */
1997int r600_init(struct radeon_device *rdev)
1998{
1999 int r;
2000
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002001 r = radeon_dummy_page_init(rdev);
2002 if (r)
2003 return r;
2004 if (r600_debugfs_mc_info_init(rdev)) {
2005 DRM_ERROR("Failed to register debugfs file for mc !\n");
2006 }
2007 /* This don't do much */
2008 r = radeon_gem_init(rdev);
2009 if (r)
2010 return r;
2011 /* Read BIOS */
2012 if (!radeon_get_bios(rdev)) {
2013 if (ASIC_IS_AVIVO(rdev))
2014 return -EINVAL;
2015 }
2016 /* Must be an ATOMBIOS */
Jerome Glissee7d40b92009-10-01 18:02:15 +02002017 if (!rdev->is_atom_bios) {
2018 dev_err(rdev->dev, "Expecting atombios for R600 GPU\n");
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002019 return -EINVAL;
Jerome Glissee7d40b92009-10-01 18:02:15 +02002020 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002021 r = radeon_atombios_init(rdev);
2022 if (r)
2023 return r;
2024 /* Post card if necessary */
Dave Airlie72542d72009-12-01 14:06:31 +10002025 if (!r600_card_posted(rdev)) {
2026 if (!rdev->bios) {
2027 dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
2028 return -EINVAL;
2029 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002030 DRM_INFO("GPU not posted. posting now...\n");
2031 atom_asic_init(rdev->mode_info.atom_context);
2032 }
2033 /* Initialize scratch registers */
2034 r600_scratch_init(rdev);
2035 /* Initialize surface registers */
2036 radeon_surface_init(rdev);
Rafał Miłecki74338742009-11-03 00:53:02 +01002037 /* Initialize clocks */
Michel Dänzer5e6dde72009-09-17 09:42:28 +02002038 radeon_get_clock_info(rdev->ddev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002039 r = radeon_clocks_init(rdev);
2040 if (r)
2041 return r;
Rafał Miłecki74338742009-11-03 00:53:02 +01002042 /* Initialize power management */
2043 radeon_pm_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002044 /* Fence driver */
2045 r = radeon_fence_driver_init(rdev);
2046 if (r)
2047 return r;
Jerome Glisse700a0cc2010-01-13 15:16:38 +01002048 if (rdev->flags & RADEON_IS_AGP) {
2049 r = radeon_agp_init(rdev);
2050 if (r)
2051 radeon_agp_disable(rdev);
2052 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002053 r = r600_mc_init(rdev);
Jerome Glisseb574f252009-10-06 19:04:29 +02002054 if (r)
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002055 return r;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002056 /* Memory manager */
Jerome Glisse4c788672009-11-20 14:29:23 +01002057 r = radeon_bo_init(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002058 if (r)
2059 return r;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002060
2061 r = radeon_irq_kms_init(rdev);
2062 if (r)
2063 return r;
2064
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002065 rdev->cp.ring_obj = NULL;
2066 r600_ring_init(rdev, 1024 * 1024);
2067
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002068 rdev->ih.ring_obj = NULL;
2069 r600_ih_ring_init(rdev, 64 * 1024);
2070
Jerome Glisse4aac0472009-09-14 18:29:49 +02002071 r = r600_pcie_gart_init(rdev);
2072 if (r)
2073 return r;
2074
Alex Deucher779720a2009-12-09 19:31:44 -05002075 rdev->accel_working = true;
Dave Airliefc30b8e2009-09-18 15:19:37 +10002076 r = r600_startup(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002077 if (r) {
Jerome Glisse655efd32010-02-02 11:51:45 +01002078 dev_err(rdev->dev, "disabling GPU acceleration\n");
2079 r600_cp_fini(rdev);
Jerome Glisse75c81292009-10-01 18:02:14 +02002080 r600_wb_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01002081 r600_irq_fini(rdev);
2082 radeon_irq_kms_fini(rdev);
Jerome Glisse75c81292009-10-01 18:02:14 +02002083 r600_pcie_gart_fini(rdev);
Jerome Glisse733289c2009-09-16 15:24:21 +02002084 rdev->accel_working = false;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002085 }
Jerome Glisse733289c2009-09-16 15:24:21 +02002086 if (rdev->accel_working) {
2087 r = radeon_ib_pool_init(rdev);
2088 if (r) {
Jerome Glissedb963802010-01-17 21:21:56 +01002089 dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
Jerome Glisse733289c2009-09-16 15:24:21 +02002090 rdev->accel_working = false;
Jerome Glissedb963802010-01-17 21:21:56 +01002091 } else {
2092 r = r600_ib_test(rdev);
2093 if (r) {
2094 dev_err(rdev->dev, "IB test failed (%d).\n", r);
2095 rdev->accel_working = false;
2096 }
Jerome Glisse733289c2009-09-16 15:24:21 +02002097 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002098 }
Christian Koenigdafc3bd2009-10-11 23:49:13 +02002099
2100 r = r600_audio_init(rdev);
2101 if (r)
2102 return r; /* TODO error handling */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002103 return 0;
2104}
2105
2106void r600_fini(struct radeon_device *rdev)
2107{
Christian Koenigdafc3bd2009-10-11 23:49:13 +02002108 r600_audio_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002109 r600_blit_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01002110 r600_cp_fini(rdev);
2111 r600_wb_fini(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002112 r600_irq_fini(rdev);
2113 radeon_irq_kms_fini(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +02002114 r600_pcie_gart_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01002115 radeon_agp_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002116 radeon_gem_fini(rdev);
2117 radeon_fence_driver_fini(rdev);
2118 radeon_clocks_fini(rdev);
Jerome Glisse4c788672009-11-20 14:29:23 +01002119 radeon_bo_fini(rdev);
Jerome Glissee7d40b92009-10-01 18:02:15 +02002120 radeon_atombios_fini(rdev);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002121 kfree(rdev->bios);
2122 rdev->bios = NULL;
2123 radeon_dummy_page_fini(rdev);
2124}
2125
2126
2127/*
2128 * CS stuff
2129 */
2130void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
2131{
2132 /* FIXME: implement */
2133 radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
2134 radeon_ring_write(rdev, ib->gpu_addr & 0xFFFFFFFC);
2135 radeon_ring_write(rdev, upper_32_bits(ib->gpu_addr) & 0xFF);
2136 radeon_ring_write(rdev, ib->length_dw);
2137}
2138
2139int r600_ib_test(struct radeon_device *rdev)
2140{
2141 struct radeon_ib *ib;
2142 uint32_t scratch;
2143 uint32_t tmp = 0;
2144 unsigned i;
2145 int r;
2146
2147 r = radeon_scratch_get(rdev, &scratch);
2148 if (r) {
2149 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
2150 return r;
2151 }
2152 WREG32(scratch, 0xCAFEDEAD);
2153 r = radeon_ib_get(rdev, &ib);
2154 if (r) {
2155 DRM_ERROR("radeon: failed to get ib (%d).\n", r);
2156 return r;
2157 }
2158 ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1);
2159 ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
2160 ib->ptr[2] = 0xDEADBEEF;
2161 ib->ptr[3] = PACKET2(0);
2162 ib->ptr[4] = PACKET2(0);
2163 ib->ptr[5] = PACKET2(0);
2164 ib->ptr[6] = PACKET2(0);
2165 ib->ptr[7] = PACKET2(0);
2166 ib->ptr[8] = PACKET2(0);
2167 ib->ptr[9] = PACKET2(0);
2168 ib->ptr[10] = PACKET2(0);
2169 ib->ptr[11] = PACKET2(0);
2170 ib->ptr[12] = PACKET2(0);
2171 ib->ptr[13] = PACKET2(0);
2172 ib->ptr[14] = PACKET2(0);
2173 ib->ptr[15] = PACKET2(0);
2174 ib->length_dw = 16;
2175 r = radeon_ib_schedule(rdev, ib);
2176 if (r) {
2177 radeon_scratch_free(rdev, scratch);
2178 radeon_ib_free(rdev, &ib);
2179 DRM_ERROR("radeon: failed to schedule ib (%d).\n", r);
2180 return r;
2181 }
2182 r = radeon_fence_wait(ib->fence, false);
2183 if (r) {
2184 DRM_ERROR("radeon: fence wait failed (%d).\n", r);
2185 return r;
2186 }
2187 for (i = 0; i < rdev->usec_timeout; i++) {
2188 tmp = RREG32(scratch);
2189 if (tmp == 0xDEADBEEF)
2190 break;
2191 DRM_UDELAY(1);
2192 }
2193 if (i < rdev->usec_timeout) {
2194 DRM_INFO("ib test succeeded in %u usecs\n", i);
2195 } else {
2196 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
2197 scratch, tmp);
2198 r = -EINVAL;
2199 }
2200 radeon_scratch_free(rdev, scratch);
2201 radeon_ib_free(rdev, &ib);
2202 return r;
2203}
2204
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002205/*
2206 * Interrupts
2207 *
2208 * Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty
2209 * the same as the CP ring buffer, but in reverse. Rather than the CPU
2210 * writing to the ring and the GPU consuming, the GPU writes to the ring
2211 * and host consumes. As the host irq handler processes interrupts, it
2212 * increments the rptr. When the rptr catches up with the wptr, all the
2213 * current interrupts have been processed.
2214 */
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002215
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002216void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
2217{
2218 u32 rb_bufsz;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002219
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002220 /* Align ring size */
2221 rb_bufsz = drm_order(ring_size / 4);
2222 ring_size = (1 << rb_bufsz) * 4;
2223 rdev->ih.ring_size = ring_size;
Jerome Glisse0c452492010-01-15 14:44:37 +01002224 rdev->ih.ptr_mask = rdev->ih.ring_size - 1;
2225 rdev->ih.rptr = 0;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002226}
2227
Jerome Glisse0c452492010-01-15 14:44:37 +01002228static int r600_ih_ring_alloc(struct radeon_device *rdev)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002229{
2230 int r;
2231
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002232 /* Allocate ring buffer */
2233 if (rdev->ih.ring_obj == NULL) {
Jerome Glisse4c788672009-11-20 14:29:23 +01002234 r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size,
2235 true,
2236 RADEON_GEM_DOMAIN_GTT,
2237 &rdev->ih.ring_obj);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002238 if (r) {
2239 DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r);
2240 return r;
2241 }
Jerome Glisse4c788672009-11-20 14:29:23 +01002242 r = radeon_bo_reserve(rdev->ih.ring_obj, false);
2243 if (unlikely(r != 0))
2244 return r;
2245 r = radeon_bo_pin(rdev->ih.ring_obj,
2246 RADEON_GEM_DOMAIN_GTT,
2247 &rdev->ih.gpu_addr);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002248 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +01002249 radeon_bo_unreserve(rdev->ih.ring_obj);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002250 DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r);
2251 return r;
2252 }
Jerome Glisse4c788672009-11-20 14:29:23 +01002253 r = radeon_bo_kmap(rdev->ih.ring_obj,
2254 (void **)&rdev->ih.ring);
2255 radeon_bo_unreserve(rdev->ih.ring_obj);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002256 if (r) {
2257 DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r);
2258 return r;
2259 }
2260 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002261 return 0;
2262}
2263
2264static void r600_ih_ring_fini(struct radeon_device *rdev)
2265{
Jerome Glisse4c788672009-11-20 14:29:23 +01002266 int r;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002267 if (rdev->ih.ring_obj) {
Jerome Glisse4c788672009-11-20 14:29:23 +01002268 r = radeon_bo_reserve(rdev->ih.ring_obj, false);
2269 if (likely(r == 0)) {
2270 radeon_bo_kunmap(rdev->ih.ring_obj);
2271 radeon_bo_unpin(rdev->ih.ring_obj);
2272 radeon_bo_unreserve(rdev->ih.ring_obj);
2273 }
2274 radeon_bo_unref(&rdev->ih.ring_obj);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002275 rdev->ih.ring = NULL;
2276 rdev->ih.ring_obj = NULL;
2277 }
2278}
2279
2280static void r600_rlc_stop(struct radeon_device *rdev)
2281{
2282
2283 if (rdev->family >= CHIP_RV770) {
2284 /* r7xx asics need to soft reset RLC before halting */
2285 WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
2286 RREG32(SRBM_SOFT_RESET);
2287 udelay(15000);
2288 WREG32(SRBM_SOFT_RESET, 0);
2289 RREG32(SRBM_SOFT_RESET);
2290 }
2291
2292 WREG32(RLC_CNTL, 0);
2293}
2294
2295static void r600_rlc_start(struct radeon_device *rdev)
2296{
2297 WREG32(RLC_CNTL, RLC_ENABLE);
2298}
2299
2300static int r600_rlc_init(struct radeon_device *rdev)
2301{
2302 u32 i;
2303 const __be32 *fw_data;
2304
2305 if (!rdev->rlc_fw)
2306 return -EINVAL;
2307
2308 r600_rlc_stop(rdev);
2309
2310 WREG32(RLC_HB_BASE, 0);
2311 WREG32(RLC_HB_CNTL, 0);
2312 WREG32(RLC_HB_RPTR, 0);
2313 WREG32(RLC_HB_WPTR, 0);
2314 WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
2315 WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
2316 WREG32(RLC_MC_CNTL, 0);
2317 WREG32(RLC_UCODE_CNTL, 0);
2318
2319 fw_data = (const __be32 *)rdev->rlc_fw->data;
2320 if (rdev->family >= CHIP_RV770) {
2321 for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
2322 WREG32(RLC_UCODE_ADDR, i);
2323 WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
2324 }
2325 } else {
2326 for (i = 0; i < RLC_UCODE_SIZE; i++) {
2327 WREG32(RLC_UCODE_ADDR, i);
2328 WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
2329 }
2330 }
2331 WREG32(RLC_UCODE_ADDR, 0);
2332
2333 r600_rlc_start(rdev);
2334
2335 return 0;
2336}
2337
2338static void r600_enable_interrupts(struct radeon_device *rdev)
2339{
2340 u32 ih_cntl = RREG32(IH_CNTL);
2341 u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
2342
2343 ih_cntl |= ENABLE_INTR;
2344 ih_rb_cntl |= IH_RB_ENABLE;
2345 WREG32(IH_CNTL, ih_cntl);
2346 WREG32(IH_RB_CNTL, ih_rb_cntl);
2347 rdev->ih.enabled = true;
2348}
2349
2350static void r600_disable_interrupts(struct radeon_device *rdev)
2351{
2352 u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
2353 u32 ih_cntl = RREG32(IH_CNTL);
2354
2355 ih_rb_cntl &= ~IH_RB_ENABLE;
2356 ih_cntl &= ~ENABLE_INTR;
2357 WREG32(IH_RB_CNTL, ih_rb_cntl);
2358 WREG32(IH_CNTL, ih_cntl);
2359 /* set rptr, wptr to 0 */
2360 WREG32(IH_RB_RPTR, 0);
2361 WREG32(IH_RB_WPTR, 0);
2362 rdev->ih.enabled = false;
2363 rdev->ih.wptr = 0;
2364 rdev->ih.rptr = 0;
2365}
2366
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002367static void r600_disable_interrupt_state(struct radeon_device *rdev)
2368{
2369 u32 tmp;
2370
2371 WREG32(CP_INT_CNTL, 0);
2372 WREG32(GRBM_INT_CNTL, 0);
2373 WREG32(DxMODE_INT_MASK, 0);
2374 if (ASIC_IS_DCE3(rdev)) {
2375 WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
2376 WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
2377 tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2378 WREG32(DC_HPD1_INT_CONTROL, tmp);
2379 tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2380 WREG32(DC_HPD2_INT_CONTROL, tmp);
2381 tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2382 WREG32(DC_HPD3_INT_CONTROL, tmp);
2383 tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2384 WREG32(DC_HPD4_INT_CONTROL, tmp);
2385 if (ASIC_IS_DCE32(rdev)) {
2386 tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2387 WREG32(DC_HPD5_INT_CONTROL, 0);
2388 tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
2389 WREG32(DC_HPD6_INT_CONTROL, 0);
2390 }
2391 } else {
2392 WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
2393 WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
2394 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2395 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0);
2396 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2397 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0);
2398 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
2399 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0);
2400 }
2401}
2402
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002403int r600_irq_init(struct radeon_device *rdev)
2404{
2405 int ret = 0;
2406 int rb_bufsz;
2407 u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
2408
2409 /* allocate ring */
Jerome Glisse0c452492010-01-15 14:44:37 +01002410 ret = r600_ih_ring_alloc(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002411 if (ret)
2412 return ret;
2413
2414 /* disable irqs */
2415 r600_disable_interrupts(rdev);
2416
2417 /* init rlc */
2418 ret = r600_rlc_init(rdev);
2419 if (ret) {
2420 r600_ih_ring_fini(rdev);
2421 return ret;
2422 }
2423
2424 /* setup interrupt control */
2425 /* set dummy read address to ring address */
2426 WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
2427 interrupt_cntl = RREG32(INTERRUPT_CNTL);
2428 /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
2429 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
2430 */
2431 interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
2432 /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
2433 interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
2434 WREG32(INTERRUPT_CNTL, interrupt_cntl);
2435
2436 WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
2437 rb_bufsz = drm_order(rdev->ih.ring_size / 4);
2438
2439 ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
2440 IH_WPTR_OVERFLOW_CLEAR |
2441 (rb_bufsz << 1));
2442 /* WPTR writeback, not yet */
2443 /*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/
2444 WREG32(IH_RB_WPTR_ADDR_LO, 0);
2445 WREG32(IH_RB_WPTR_ADDR_HI, 0);
2446
2447 WREG32(IH_RB_CNTL, ih_rb_cntl);
2448
2449 /* set rptr, wptr to 0 */
2450 WREG32(IH_RB_RPTR, 0);
2451 WREG32(IH_RB_WPTR, 0);
2452
2453 /* Default settings for IH_CNTL (disabled at first) */
2454 ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10);
2455 /* RPTR_REARM only works if msi's are enabled */
2456 if (rdev->msi_enabled)
2457 ih_cntl |= RPTR_REARM;
2458
2459#ifdef __BIG_ENDIAN
2460 ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT);
2461#endif
2462 WREG32(IH_CNTL, ih_cntl);
2463
2464 /* force the active interrupt state to all disabled */
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002465 r600_disable_interrupt_state(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002466
2467 /* enable irqs */
2468 r600_enable_interrupts(rdev);
2469
2470 return ret;
2471}
2472
Jerome Glisse0c452492010-01-15 14:44:37 +01002473void r600_irq_suspend(struct radeon_device *rdev)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002474{
2475 r600_disable_interrupts(rdev);
2476 r600_rlc_stop(rdev);
Jerome Glisse0c452492010-01-15 14:44:37 +01002477}
2478
2479void r600_irq_fini(struct radeon_device *rdev)
2480{
2481 r600_irq_suspend(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002482 r600_ih_ring_fini(rdev);
2483}
2484
2485int r600_irq_set(struct radeon_device *rdev)
2486{
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002487 u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
2488 u32 mode_int = 0;
2489 u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002490
Jerome Glisse003e69f2010-01-07 15:39:14 +01002491 if (!rdev->irq.installed) {
2492 WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
2493 return -EINVAL;
2494 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002495 /* don't enable anything if the ih is disabled */
Jerome Glisse79c2bbc2010-01-15 14:44:38 +01002496 if (!rdev->ih.enabled) {
2497 r600_disable_interrupts(rdev);
2498 /* force the active interrupt state to all disabled */
2499 r600_disable_interrupt_state(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002500 return 0;
Jerome Glisse79c2bbc2010-01-15 14:44:38 +01002501 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002502
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002503 if (ASIC_IS_DCE3(rdev)) {
2504 hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
2505 hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
2506 hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
2507 hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
2508 if (ASIC_IS_DCE32(rdev)) {
2509 hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
2510 hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
2511 }
2512 } else {
2513 hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN;
2514 hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN;
2515 hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
2516 }
2517
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002518 if (rdev->irq.sw_int) {
2519 DRM_DEBUG("r600_irq_set: sw int\n");
2520 cp_int_cntl |= RB_INT_ENABLE;
2521 }
2522 if (rdev->irq.crtc_vblank_int[0]) {
2523 DRM_DEBUG("r600_irq_set: vblank 0\n");
2524 mode_int |= D1MODE_VBLANK_INT_MASK;
2525 }
2526 if (rdev->irq.crtc_vblank_int[1]) {
2527 DRM_DEBUG("r600_irq_set: vblank 1\n");
2528 mode_int |= D2MODE_VBLANK_INT_MASK;
2529 }
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002530 if (rdev->irq.hpd[0]) {
2531 DRM_DEBUG("r600_irq_set: hpd 1\n");
2532 hpd1 |= DC_HPDx_INT_EN;
2533 }
2534 if (rdev->irq.hpd[1]) {
2535 DRM_DEBUG("r600_irq_set: hpd 2\n");
2536 hpd2 |= DC_HPDx_INT_EN;
2537 }
2538 if (rdev->irq.hpd[2]) {
2539 DRM_DEBUG("r600_irq_set: hpd 3\n");
2540 hpd3 |= DC_HPDx_INT_EN;
2541 }
2542 if (rdev->irq.hpd[3]) {
2543 DRM_DEBUG("r600_irq_set: hpd 4\n");
2544 hpd4 |= DC_HPDx_INT_EN;
2545 }
2546 if (rdev->irq.hpd[4]) {
2547 DRM_DEBUG("r600_irq_set: hpd 5\n");
2548 hpd5 |= DC_HPDx_INT_EN;
2549 }
2550 if (rdev->irq.hpd[5]) {
2551 DRM_DEBUG("r600_irq_set: hpd 6\n");
2552 hpd6 |= DC_HPDx_INT_EN;
2553 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002554
2555 WREG32(CP_INT_CNTL, cp_int_cntl);
2556 WREG32(DxMODE_INT_MASK, mode_int);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002557 if (ASIC_IS_DCE3(rdev)) {
2558 WREG32(DC_HPD1_INT_CONTROL, hpd1);
2559 WREG32(DC_HPD2_INT_CONTROL, hpd2);
2560 WREG32(DC_HPD3_INT_CONTROL, hpd3);
2561 WREG32(DC_HPD4_INT_CONTROL, hpd4);
2562 if (ASIC_IS_DCE32(rdev)) {
2563 WREG32(DC_HPD5_INT_CONTROL, hpd5);
2564 WREG32(DC_HPD6_INT_CONTROL, hpd6);
2565 }
2566 } else {
2567 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
2568 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
2569 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
2570 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002571
2572 return 0;
2573}
2574
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002575static inline void r600_irq_ack(struct radeon_device *rdev,
2576 u32 *disp_int,
2577 u32 *disp_int_cont,
2578 u32 *disp_int_cont2)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002579{
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002580 u32 tmp;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002581
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002582 if (ASIC_IS_DCE3(rdev)) {
2583 *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
2584 *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
2585 *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
2586 } else {
2587 *disp_int = RREG32(DISP_INTERRUPT_STATUS);
2588 *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
2589 *disp_int_cont2 = 0;
2590 }
2591
2592 if (*disp_int & LB_D1_VBLANK_INTERRUPT)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002593 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002594 if (*disp_int & LB_D1_VLINE_INTERRUPT)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002595 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002596 if (*disp_int & LB_D2_VBLANK_INTERRUPT)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002597 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002598 if (*disp_int & LB_D2_VLINE_INTERRUPT)
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002599 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002600 if (*disp_int & DC_HPD1_INTERRUPT) {
2601 if (ASIC_IS_DCE3(rdev)) {
2602 tmp = RREG32(DC_HPD1_INT_CONTROL);
2603 tmp |= DC_HPDx_INT_ACK;
2604 WREG32(DC_HPD1_INT_CONTROL, tmp);
2605 } else {
2606 tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
2607 tmp |= DC_HPDx_INT_ACK;
2608 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
2609 }
2610 }
2611 if (*disp_int & DC_HPD2_INTERRUPT) {
2612 if (ASIC_IS_DCE3(rdev)) {
2613 tmp = RREG32(DC_HPD2_INT_CONTROL);
2614 tmp |= DC_HPDx_INT_ACK;
2615 WREG32(DC_HPD2_INT_CONTROL, tmp);
2616 } else {
2617 tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
2618 tmp |= DC_HPDx_INT_ACK;
2619 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
2620 }
2621 }
2622 if (*disp_int_cont & DC_HPD3_INTERRUPT) {
2623 if (ASIC_IS_DCE3(rdev)) {
2624 tmp = RREG32(DC_HPD3_INT_CONTROL);
2625 tmp |= DC_HPDx_INT_ACK;
2626 WREG32(DC_HPD3_INT_CONTROL, tmp);
2627 } else {
2628 tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
2629 tmp |= DC_HPDx_INT_ACK;
2630 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
2631 }
2632 }
2633 if (*disp_int_cont & DC_HPD4_INTERRUPT) {
2634 tmp = RREG32(DC_HPD4_INT_CONTROL);
2635 tmp |= DC_HPDx_INT_ACK;
2636 WREG32(DC_HPD4_INT_CONTROL, tmp);
2637 }
2638 if (ASIC_IS_DCE32(rdev)) {
2639 if (*disp_int_cont2 & DC_HPD5_INTERRUPT) {
2640 tmp = RREG32(DC_HPD5_INT_CONTROL);
2641 tmp |= DC_HPDx_INT_ACK;
2642 WREG32(DC_HPD5_INT_CONTROL, tmp);
2643 }
2644 if (*disp_int_cont2 & DC_HPD6_INTERRUPT) {
2645 tmp = RREG32(DC_HPD5_INT_CONTROL);
2646 tmp |= DC_HPDx_INT_ACK;
2647 WREG32(DC_HPD6_INT_CONTROL, tmp);
2648 }
2649 }
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002650}
2651
2652void r600_irq_disable(struct radeon_device *rdev)
2653{
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002654 u32 disp_int, disp_int_cont, disp_int_cont2;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002655
2656 r600_disable_interrupts(rdev);
2657 /* Wait and acknowledge irq */
2658 mdelay(1);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002659 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
2660 r600_disable_interrupt_state(rdev);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002661}
2662
2663static inline u32 r600_get_ih_wptr(struct radeon_device *rdev)
2664{
2665 u32 wptr, tmp;
2666
2667 /* XXX use writeback */
2668 wptr = RREG32(IH_RB_WPTR);
2669
2670 if (wptr & RB_OVERFLOW) {
Jerome Glisse7924e5e2010-01-15 14:44:39 +01002671 /* When a ring buffer overflow happen start parsing interrupt
2672 * from the last not overwritten vector (wptr + 16). Hopefully
2673 * this should allow us to catchup.
2674 */
2675 dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
2676 wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
2677 rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002678 tmp = RREG32(IH_RB_CNTL);
2679 tmp |= IH_WPTR_OVERFLOW_CLEAR;
2680 WREG32(IH_RB_CNTL, tmp);
2681 }
Jerome Glisse0c452492010-01-15 14:44:37 +01002682 return (wptr & rdev->ih.ptr_mask);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002683}
2684
2685/* r600 IV Ring
2686 * Each IV ring entry is 128 bits:
2687 * [7:0] - interrupt source id
2688 * [31:8] - reserved
2689 * [59:32] - interrupt source data
2690 * [127:60] - reserved
2691 *
2692 * The basic interrupt vector entries
2693 * are decoded as follows:
2694 * src_id src_data description
2695 * 1 0 D1 Vblank
2696 * 1 1 D1 Vline
2697 * 5 0 D2 Vblank
2698 * 5 1 D2 Vline
2699 * 19 0 FP Hot plug detection A
2700 * 19 1 FP Hot plug detection B
2701 * 19 2 DAC A auto-detection
2702 * 19 3 DAC B auto-detection
2703 * 176 - CP_INT RB
2704 * 177 - CP_INT IB1
2705 * 178 - CP_INT IB2
2706 * 181 - EOP Interrupt
2707 * 233 - GUI Idle
2708 *
2709 * Note, these are based on r600 and may need to be
2710 * adjusted or added to on newer asics
2711 */
2712
2713int r600_irq_process(struct radeon_device *rdev)
2714{
2715 u32 wptr = r600_get_ih_wptr(rdev);
2716 u32 rptr = rdev->ih.rptr;
2717 u32 src_id, src_data;
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002718 u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002719 unsigned long flags;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002720 bool queue_hotplug = false;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002721
2722 DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
Jerome Glisse79c2bbc2010-01-15 14:44:38 +01002723 if (!rdev->ih.enabled)
2724 return IRQ_NONE;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002725
2726 spin_lock_irqsave(&rdev->ih.lock, flags);
2727
2728 if (rptr == wptr) {
2729 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2730 return IRQ_NONE;
2731 }
2732 if (rdev->shutdown) {
2733 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2734 return IRQ_NONE;
2735 }
2736
2737restart_ih:
2738 /* display interrupts */
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002739 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002740
2741 rdev->ih.wptr = wptr;
2742 while (rptr != wptr) {
2743 /* wptr/rptr are in bytes! */
2744 ring_index = rptr / 4;
2745 src_id = rdev->ih.ring[ring_index] & 0xff;
2746 src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff;
2747
2748 switch (src_id) {
2749 case 1: /* D1 vblank/vline */
2750 switch (src_data) {
2751 case 0: /* D1 vblank */
2752 if (disp_int & LB_D1_VBLANK_INTERRUPT) {
2753 drm_handle_vblank(rdev->ddev, 0);
Rafał Miłecki73a6d3f2010-01-08 00:22:47 +01002754 wake_up(&rdev->irq.vblank_queue);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002755 disp_int &= ~LB_D1_VBLANK_INTERRUPT;
2756 DRM_DEBUG("IH: D1 vblank\n");
2757 }
2758 break;
2759 case 1: /* D1 vline */
2760 if (disp_int & LB_D1_VLINE_INTERRUPT) {
2761 disp_int &= ~LB_D1_VLINE_INTERRUPT;
2762 DRM_DEBUG("IH: D1 vline\n");
2763 }
2764 break;
2765 default:
Alex Deucherb0425892010-01-11 19:47:38 -05002766 DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002767 break;
2768 }
2769 break;
2770 case 5: /* D2 vblank/vline */
2771 switch (src_data) {
2772 case 0: /* D2 vblank */
2773 if (disp_int & LB_D2_VBLANK_INTERRUPT) {
2774 drm_handle_vblank(rdev->ddev, 1);
Rafał Miłecki73a6d3f2010-01-08 00:22:47 +01002775 wake_up(&rdev->irq.vblank_queue);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002776 disp_int &= ~LB_D2_VBLANK_INTERRUPT;
2777 DRM_DEBUG("IH: D2 vblank\n");
2778 }
2779 break;
2780 case 1: /* D1 vline */
2781 if (disp_int & LB_D2_VLINE_INTERRUPT) {
2782 disp_int &= ~LB_D2_VLINE_INTERRUPT;
2783 DRM_DEBUG("IH: D2 vline\n");
2784 }
2785 break;
2786 default:
Alex Deucherb0425892010-01-11 19:47:38 -05002787 DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002788 break;
2789 }
2790 break;
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002791 case 19: /* HPD/DAC hotplug */
2792 switch (src_data) {
2793 case 0:
2794 if (disp_int & DC_HPD1_INTERRUPT) {
2795 disp_int &= ~DC_HPD1_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002796 queue_hotplug = true;
2797 DRM_DEBUG("IH: HPD1\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002798 }
2799 break;
2800 case 1:
2801 if (disp_int & DC_HPD2_INTERRUPT) {
2802 disp_int &= ~DC_HPD2_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002803 queue_hotplug = true;
2804 DRM_DEBUG("IH: HPD2\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002805 }
2806 break;
2807 case 4:
2808 if (disp_int_cont & DC_HPD3_INTERRUPT) {
2809 disp_int_cont &= ~DC_HPD3_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002810 queue_hotplug = true;
2811 DRM_DEBUG("IH: HPD3\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002812 }
2813 break;
2814 case 5:
2815 if (disp_int_cont & DC_HPD4_INTERRUPT) {
2816 disp_int_cont &= ~DC_HPD4_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002817 queue_hotplug = true;
2818 DRM_DEBUG("IH: HPD4\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002819 }
2820 break;
2821 case 10:
2822 if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
2823 disp_int_cont &= ~DC_HPD5_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002824 queue_hotplug = true;
2825 DRM_DEBUG("IH: HPD5\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002826 }
2827 break;
2828 case 12:
2829 if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
2830 disp_int_cont &= ~DC_HPD6_INTERRUPT;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002831 queue_hotplug = true;
2832 DRM_DEBUG("IH: HPD6\n");
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002833 }
2834 break;
2835 default:
Alex Deucherb0425892010-01-11 19:47:38 -05002836 DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Alex Deuchere0df1ac2009-12-04 15:12:21 -05002837 break;
2838 }
2839 break;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002840 case 176: /* CP_INT in ring buffer */
2841 case 177: /* CP_INT in IB1 */
2842 case 178: /* CP_INT in IB2 */
2843 DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
2844 radeon_fence_process(rdev);
2845 break;
2846 case 181: /* CP EOP event */
2847 DRM_DEBUG("IH: CP EOP\n");
2848 break;
2849 default:
Alex Deucherb0425892010-01-11 19:47:38 -05002850 DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002851 break;
2852 }
2853
2854 /* wptr/rptr are in bytes! */
Jerome Glisse0c452492010-01-15 14:44:37 +01002855 rptr += 16;
2856 rptr &= rdev->ih.ptr_mask;
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002857 }
2858 /* make sure wptr hasn't changed while processing */
2859 wptr = r600_get_ih_wptr(rdev);
2860 if (wptr != rdev->ih.wptr)
2861 goto restart_ih;
Alex Deucherd4877cf2009-12-04 16:56:37 -05002862 if (queue_hotplug)
2863 queue_work(rdev->wq, &rdev->hotplug_work);
Alex Deucherd8f60cf2009-12-01 13:43:46 -05002864 rdev->ih.rptr = rptr;
2865 WREG32(IH_RB_RPTR, rdev->ih.rptr);
2866 spin_unlock_irqrestore(&rdev->ih.lock, flags);
2867 return IRQ_HANDLED;
2868}
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002869
2870/*
2871 * Debugfs info
2872 */
2873#if defined(CONFIG_DEBUG_FS)
2874
2875static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data)
2876{
2877 struct drm_info_node *node = (struct drm_info_node *) m->private;
2878 struct drm_device *dev = node->minor->dev;
2879 struct radeon_device *rdev = dev->dev_private;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002880 unsigned count, i, j;
2881
2882 radeon_ring_free_size(rdev);
Rafał Miłeckid6840762009-11-10 22:26:21 +01002883 count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002884 seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT));
Rafał Miłeckid6840762009-11-10 22:26:21 +01002885 seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR));
2886 seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR));
2887 seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr);
2888 seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr);
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002889 seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
2890 seq_printf(m, "%u dwords in ring\n", count);
Rafał Miłeckid6840762009-11-10 22:26:21 +01002891 i = rdev->cp.rptr;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002892 for (j = 0; j <= count; j++) {
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002893 seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
Rafał Miłeckid6840762009-11-10 22:26:21 +01002894 i = (i + 1) & rdev->cp.ptr_mask;
Jerome Glisse3ce0a232009-09-08 10:10:24 +10002895 }
2896 return 0;
2897}
2898
2899static int r600_debugfs_mc_info(struct seq_file *m, void *data)
2900{
2901 struct drm_info_node *node = (struct drm_info_node *) m->private;
2902 struct drm_device *dev = node->minor->dev;
2903 struct radeon_device *rdev = dev->dev_private;
2904
2905 DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS);
2906 DREG32_SYS(m, rdev, VM_L2_STATUS);
2907 return 0;
2908}
2909
2910static struct drm_info_list r600_mc_info_list[] = {
2911 {"r600_mc_info", r600_debugfs_mc_info, 0, NULL},
2912 {"r600_ring_info", r600_debugfs_cp_ring_info, 0, NULL},
2913};
2914#endif
2915
2916int r600_debugfs_mc_info_init(struct radeon_device *rdev)
2917{
2918#if defined(CONFIG_DEBUG_FS)
2919 return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list));
2920#else
2921 return 0;
2922#endif
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002923}
Jerome Glisse062b3892010-02-04 20:36:39 +01002924
2925/**
2926 * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl
2927 * rdev: radeon device structure
2928 * bo: buffer object struct which userspace is waiting for idle
2929 *
2930 * Some R6XX/R7XX doesn't seems to take into account HDP flush performed
2931 * through ring buffer, this leads to corruption in rendering, see
2932 * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we
2933 * directly perform HDP flush by writing register through MMIO.
2934 */
2935void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
2936{
2937 WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2938}