blob: e62116e222a0b6e1a441c84ecc162e42d7e2ac22 [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 */
28#include <linux/seq_file.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090029#include <linux/slab.h>
Jerome Glisse771fe6b2009-06-05 14:42:42 +020030#include "drmP.h"
31#include "drm.h"
32#include "radeon_drm.h"
Jerome Glisse771fe6b2009-06-05 14:42:42 +020033#include "radeon_reg.h"
34#include "radeon.h"
Daniel Vettere6990372010-03-11 21:19:17 +000035#include "radeon_asic.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100036#include "r100d.h"
Jerome Glissed4550902009-10-01 10:12:06 +020037#include "rs100d.h"
38#include "rv200d.h"
39#include "rv250d.h"
Jerome Glisse3ce0a232009-09-08 10:10:24 +100040
Ben Hutchings70967ab2009-08-29 14:53:51 +010041#include <linux/firmware.h>
42#include <linux/platform_device.h>
43
Dave Airlie551ebd82009-09-01 15:25:57 +100044#include "r100_reg_safe.h"
45#include "rn50_reg_safe.h"
46
Ben Hutchings70967ab2009-08-29 14:53:51 +010047/* Firmware Names */
48#define FIRMWARE_R100 "radeon/R100_cp.bin"
49#define FIRMWARE_R200 "radeon/R200_cp.bin"
50#define FIRMWARE_R300 "radeon/R300_cp.bin"
51#define FIRMWARE_R420 "radeon/R420_cp.bin"
52#define FIRMWARE_RS690 "radeon/RS690_cp.bin"
53#define FIRMWARE_RS600 "radeon/RS600_cp.bin"
54#define FIRMWARE_R520 "radeon/R520_cp.bin"
55
56MODULE_FIRMWARE(FIRMWARE_R100);
57MODULE_FIRMWARE(FIRMWARE_R200);
58MODULE_FIRMWARE(FIRMWARE_R300);
59MODULE_FIRMWARE(FIRMWARE_R420);
60MODULE_FIRMWARE(FIRMWARE_RS690);
61MODULE_FIRMWARE(FIRMWARE_RS600);
62MODULE_FIRMWARE(FIRMWARE_R520);
Jerome Glisse771fe6b2009-06-05 14:42:42 +020063
Dave Airlie551ebd82009-09-01 15:25:57 +100064#include "r100_track.h"
65
Jerome Glisse771fe6b2009-06-05 14:42:42 +020066/* This files gather functions specifics to:
67 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
Jerome Glisse771fe6b2009-06-05 14:42:42 +020068 */
Jerome Glisse771fe6b2009-06-05 14:42:42 +020069
Alex Deucherdef9ba92010-04-22 12:39:58 -040070bool r100_gui_idle(struct radeon_device *rdev)
71{
72 if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)
73 return false;
74 else
75 return true;
76}
77
Alex Deucher05a05c52009-12-04 14:53:41 -050078/* hpd for digital panel detect/disconnect */
79bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
80{
81 bool connected = false;
82
83 switch (hpd) {
84 case RADEON_HPD_1:
85 if (RREG32(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
86 connected = true;
87 break;
88 case RADEON_HPD_2:
89 if (RREG32(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
90 connected = true;
91 break;
92 default:
93 break;
94 }
95 return connected;
96}
97
98void r100_hpd_set_polarity(struct radeon_device *rdev,
99 enum radeon_hpd_id hpd)
100{
101 u32 tmp;
102 bool connected = r100_hpd_sense(rdev, hpd);
103
104 switch (hpd) {
105 case RADEON_HPD_1:
106 tmp = RREG32(RADEON_FP_GEN_CNTL);
107 if (connected)
108 tmp &= ~RADEON_FP_DETECT_INT_POL;
109 else
110 tmp |= RADEON_FP_DETECT_INT_POL;
111 WREG32(RADEON_FP_GEN_CNTL, tmp);
112 break;
113 case RADEON_HPD_2:
114 tmp = RREG32(RADEON_FP2_GEN_CNTL);
115 if (connected)
116 tmp &= ~RADEON_FP2_DETECT_INT_POL;
117 else
118 tmp |= RADEON_FP2_DETECT_INT_POL;
119 WREG32(RADEON_FP2_GEN_CNTL, tmp);
120 break;
121 default:
122 break;
123 }
124}
125
126void r100_hpd_init(struct radeon_device *rdev)
127{
128 struct drm_device *dev = rdev->ddev;
129 struct drm_connector *connector;
130
131 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
132 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
133 switch (radeon_connector->hpd.hpd) {
134 case RADEON_HPD_1:
135 rdev->irq.hpd[0] = true;
136 break;
137 case RADEON_HPD_2:
138 rdev->irq.hpd[1] = true;
139 break;
140 default:
141 break;
142 }
143 }
Jerome Glisse003e69f2010-01-07 15:39:14 +0100144 if (rdev->irq.installed)
145 r100_irq_set(rdev);
Alex Deucher05a05c52009-12-04 14:53:41 -0500146}
147
148void r100_hpd_fini(struct radeon_device *rdev)
149{
150 struct drm_device *dev = rdev->ddev;
151 struct drm_connector *connector;
152
153 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
154 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
155 switch (radeon_connector->hpd.hpd) {
156 case RADEON_HPD_1:
157 rdev->irq.hpd[0] = false;
158 break;
159 case RADEON_HPD_2:
160 rdev->irq.hpd[1] = false;
161 break;
162 default:
163 break;
164 }
165 }
166}
167
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200168/*
169 * PCI GART
170 */
171void r100_pci_gart_tlb_flush(struct radeon_device *rdev)
172{
173 /* TODO: can we do somethings here ? */
174 /* It seems hw only cache one entry so we should discard this
175 * entry otherwise if first GPU GART read hit this entry it
176 * could end up in wrong address. */
177}
178
Jerome Glisse4aac0472009-09-14 18:29:49 +0200179int r100_pci_gart_init(struct radeon_device *rdev)
180{
181 int r;
182
183 if (rdev->gart.table.ram.ptr) {
184 WARN(1, "R100 PCI GART already initialized.\n");
185 return 0;
186 }
187 /* Initialize common gart structure */
188 r = radeon_gart_init(rdev);
189 if (r)
190 return r;
191 rdev->gart.table_size = rdev->gart.num_gpu_pages * 4;
192 rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
193 rdev->asic->gart_set_page = &r100_pci_gart_set_page;
194 return radeon_gart_table_ram_alloc(rdev);
195}
196
Dave Airlie17e15b02009-11-05 15:36:53 +1000197/* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
198void r100_enable_bm(struct radeon_device *rdev)
199{
200 uint32_t tmp;
201 /* Enable bus mastering */
202 tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
203 WREG32(RADEON_BUS_CNTL, tmp);
204}
205
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200206int r100_pci_gart_enable(struct radeon_device *rdev)
207{
208 uint32_t tmp;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200209
Dave Airlie82568562010-02-05 16:00:07 +1000210 radeon_gart_restore(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200211 /* discard memory request outside of configured range */
212 tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
213 WREG32(RADEON_AIC_CNTL, tmp);
214 /* set address range for PCI address translate */
Jerome Glissed594e462010-02-17 21:54:29 +0000215 WREG32(RADEON_AIC_LO_ADDR, rdev->mc.gtt_start);
216 WREG32(RADEON_AIC_HI_ADDR, rdev->mc.gtt_end);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200217 /* set PCI GART page-table base address */
218 WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr);
219 tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN;
220 WREG32(RADEON_AIC_CNTL, tmp);
221 r100_pci_gart_tlb_flush(rdev);
222 rdev->gart.ready = true;
223 return 0;
224}
225
226void r100_pci_gart_disable(struct radeon_device *rdev)
227{
228 uint32_t tmp;
229
230 /* discard memory request outside of configured range */
231 tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS;
232 WREG32(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN);
233 WREG32(RADEON_AIC_LO_ADDR, 0);
234 WREG32(RADEON_AIC_HI_ADDR, 0);
235}
236
237int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
238{
239 if (i < 0 || i > rdev->gart.num_gpu_pages) {
240 return -EINVAL;
241 }
Dave Airlieed10f952009-06-29 18:29:11 +1000242 rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr));
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200243 return 0;
244}
245
Jerome Glisse4aac0472009-09-14 18:29:49 +0200246void r100_pci_gart_fini(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200247{
Jerome Glissef9274562010-03-17 14:44:29 +0000248 radeon_gart_fini(rdev);
Jerome Glisse4aac0472009-09-14 18:29:49 +0200249 r100_pci_gart_disable(rdev);
250 radeon_gart_table_ram_free(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200251}
252
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200253int r100_irq_set(struct radeon_device *rdev)
254{
255 uint32_t tmp = 0;
256
Jerome Glisse003e69f2010-01-07 15:39:14 +0100257 if (!rdev->irq.installed) {
258 WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
259 WREG32(R_000040_GEN_INT_CNTL, 0);
260 return -EINVAL;
261 }
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200262 if (rdev->irq.sw_int) {
263 tmp |= RADEON_SW_INT_ENABLE;
264 }
265 if (rdev->irq.crtc_vblank_int[0]) {
266 tmp |= RADEON_CRTC_VBLANK_MASK;
267 }
268 if (rdev->irq.crtc_vblank_int[1]) {
269 tmp |= RADEON_CRTC2_VBLANK_MASK;
270 }
Alex Deucher05a05c52009-12-04 14:53:41 -0500271 if (rdev->irq.hpd[0]) {
272 tmp |= RADEON_FP_DETECT_MASK;
273 }
274 if (rdev->irq.hpd[1]) {
275 tmp |= RADEON_FP2_DETECT_MASK;
276 }
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200277 WREG32(RADEON_GEN_INT_CNTL, tmp);
278 return 0;
279}
280
Jerome Glisse9f022dd2009-09-11 15:35:22 +0200281void r100_irq_disable(struct radeon_device *rdev)
282{
283 u32 tmp;
284
285 WREG32(R_000040_GEN_INT_CNTL, 0);
286 /* Wait and acknowledge irq */
287 mdelay(1);
288 tmp = RREG32(R_000044_GEN_INT_STATUS);
289 WREG32(R_000044_GEN_INT_STATUS, tmp);
290}
291
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200292static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
293{
294 uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
Alex Deucher05a05c52009-12-04 14:53:41 -0500295 uint32_t irq_mask = RADEON_SW_INT_TEST |
296 RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT |
297 RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT;
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200298
299 if (irqs) {
300 WREG32(RADEON_GEN_INT_STATUS, irqs);
301 }
302 return irqs & irq_mask;
303}
304
305int r100_irq_process(struct radeon_device *rdev)
306{
Alex Deucher3e5cb982009-10-16 12:21:24 -0400307 uint32_t status, msi_rearm;
Alex Deucherd4877cf2009-12-04 16:56:37 -0500308 bool queue_hotplug = false;
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200309
310 status = r100_irq_ack(rdev);
311 if (!status) {
312 return IRQ_NONE;
313 }
Jerome Glissea513c182009-09-09 22:23:07 +0200314 if (rdev->shutdown) {
315 return IRQ_NONE;
316 }
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200317 while (status) {
318 /* SW interrupt */
319 if (status & RADEON_SW_INT_TEST) {
320 radeon_fence_process(rdev);
321 }
322 /* Vertical blank interrupts */
323 if (status & RADEON_CRTC_VBLANK_STAT) {
324 drm_handle_vblank(rdev->ddev, 0);
Rafał Miłecki839461d2010-03-02 22:06:51 +0100325 rdev->pm.vblank_sync = true;
Rafał Miłecki73a6d3f2010-01-08 00:22:47 +0100326 wake_up(&rdev->irq.vblank_queue);
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200327 }
328 if (status & RADEON_CRTC2_VBLANK_STAT) {
329 drm_handle_vblank(rdev->ddev, 1);
Rafał Miłecki839461d2010-03-02 22:06:51 +0100330 rdev->pm.vblank_sync = true;
Rafał Miłecki73a6d3f2010-01-08 00:22:47 +0100331 wake_up(&rdev->irq.vblank_queue);
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200332 }
Alex Deucher05a05c52009-12-04 14:53:41 -0500333 if (status & RADEON_FP_DETECT_STAT) {
Alex Deucherd4877cf2009-12-04 16:56:37 -0500334 queue_hotplug = true;
335 DRM_DEBUG("HPD1\n");
Alex Deucher05a05c52009-12-04 14:53:41 -0500336 }
337 if (status & RADEON_FP2_DETECT_STAT) {
Alex Deucherd4877cf2009-12-04 16:56:37 -0500338 queue_hotplug = true;
339 DRM_DEBUG("HPD2\n");
Alex Deucher05a05c52009-12-04 14:53:41 -0500340 }
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200341 status = r100_irq_ack(rdev);
342 }
Alex Deucherd4877cf2009-12-04 16:56:37 -0500343 if (queue_hotplug)
344 queue_work(rdev->wq, &rdev->hotplug_work);
Alex Deucher3e5cb982009-10-16 12:21:24 -0400345 if (rdev->msi_enabled) {
346 switch (rdev->family) {
347 case CHIP_RS400:
348 case CHIP_RS480:
349 msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM;
350 WREG32(RADEON_AIC_CNTL, msi_rearm);
351 WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM);
352 break;
353 default:
354 msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN;
355 WREG32(RADEON_MSI_REARM_EN, msi_rearm);
356 WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN);
357 break;
358 }
359 }
Michel Dänzer7ed220d2009-08-13 11:10:51 +0200360 return IRQ_HANDLED;
361}
362
363u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc)
364{
365 if (crtc == 0)
366 return RREG32(RADEON_CRTC_CRNT_FRAME);
367 else
368 return RREG32(RADEON_CRTC2_CRNT_FRAME);
369}
370
Pauli Nieminen9e5b2af2010-02-04 19:20:53 +0200371/* Who ever call radeon_fence_emit should call ring_lock and ask
372 * for enough space (today caller are ib schedule and buffer move) */
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200373void r100_fence_ring_emit(struct radeon_device *rdev,
374 struct radeon_fence *fence)
375{
Pauli Nieminen9e5b2af2010-02-04 19:20:53 +0200376 /* We have to make sure that caches are flushed before
377 * CPU might read something from VRAM. */
378 radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));
379 radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL);
380 radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0));
381 radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200382 /* Wait until IDLE & CLEAN */
Alex Deucher4612dc92010-02-05 01:58:28 -0500383 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
384 radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
Jerome Glissecafe6602010-01-07 12:39:21 +0100385 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
386 radeon_ring_write(rdev, rdev->config.r100.hdp_cntl |
387 RADEON_HDP_READ_BUFFER_INVALIDATE);
388 radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0));
389 radeon_ring_write(rdev, rdev->config.r100.hdp_cntl);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200390 /* Emit fence sequence & fire IRQ */
391 radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0));
392 radeon_ring_write(rdev, fence->seq);
393 radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0));
394 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
395}
396
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200397int r100_wb_init(struct radeon_device *rdev)
398{
399 int r;
400
401 if (rdev->wb.wb_obj == NULL) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100402 r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true,
403 RADEON_GEM_DOMAIN_GTT,
404 &rdev->wb.wb_obj);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200405 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100406 dev_err(rdev->dev, "(%d) create WB buffer failed\n", r);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200407 return r;
408 }
Jerome Glisse4c788672009-11-20 14:29:23 +0100409 r = radeon_bo_reserve(rdev->wb.wb_obj, false);
410 if (unlikely(r != 0))
411 return r;
412 r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT,
413 &rdev->wb.gpu_addr);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200414 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100415 dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r);
416 radeon_bo_unreserve(rdev->wb.wb_obj);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200417 return r;
418 }
Jerome Glisse4c788672009-11-20 14:29:23 +0100419 r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb);
420 radeon_bo_unreserve(rdev->wb.wb_obj);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200421 if (r) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100422 dev_err(rdev->dev, "(%d) map WB buffer failed\n", r);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200423 return r;
424 }
425 }
Jerome Glisse9f022dd2009-09-11 15:35:22 +0200426 WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr);
427 WREG32(R_00070C_CP_RB_RPTR_ADDR,
428 S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + 1024) >> 2));
429 WREG32(R_000770_SCRATCH_UMSK, 0xff);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200430 return 0;
431}
432
Jerome Glisse9f022dd2009-09-11 15:35:22 +0200433void r100_wb_disable(struct radeon_device *rdev)
434{
435 WREG32(R_000770_SCRATCH_UMSK, 0);
436}
437
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200438void r100_wb_fini(struct radeon_device *rdev)
439{
Jerome Glisse4c788672009-11-20 14:29:23 +0100440 int r;
441
Jerome Glisse9f022dd2009-09-11 15:35:22 +0200442 r100_wb_disable(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200443 if (rdev->wb.wb_obj) {
Jerome Glisse4c788672009-11-20 14:29:23 +0100444 r = radeon_bo_reserve(rdev->wb.wb_obj, false);
445 if (unlikely(r != 0)) {
446 dev_err(rdev->dev, "(%d) can't finish WB\n", r);
447 return;
448 }
449 radeon_bo_kunmap(rdev->wb.wb_obj);
450 radeon_bo_unpin(rdev->wb.wb_obj);
451 radeon_bo_unreserve(rdev->wb.wb_obj);
452 radeon_bo_unref(&rdev->wb.wb_obj);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200453 rdev->wb.wb = NULL;
454 rdev->wb.wb_obj = NULL;
455 }
456}
457
458int r100_copy_blit(struct radeon_device *rdev,
459 uint64_t src_offset,
460 uint64_t dst_offset,
461 unsigned num_pages,
462 struct radeon_fence *fence)
463{
464 uint32_t cur_pages;
465 uint32_t stride_bytes = PAGE_SIZE;
466 uint32_t pitch;
467 uint32_t stride_pixels;
468 unsigned ndw;
469 int num_loops;
470 int r = 0;
471
472 /* radeon limited to 16k stride */
473 stride_bytes &= 0x3fff;
474 /* radeon pitch is /64 */
475 pitch = stride_bytes / 64;
476 stride_pixels = stride_bytes / 4;
477 num_loops = DIV_ROUND_UP(num_pages, 8191);
478
479 /* Ask for enough room for blit + flush + fence */
480 ndw = 64 + (10 * num_loops);
481 r = radeon_ring_lock(rdev, ndw);
482 if (r) {
483 DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw);
484 return -EINVAL;
485 }
486 while (num_pages > 0) {
487 cur_pages = num_pages;
488 if (cur_pages > 8191) {
489 cur_pages = 8191;
490 }
491 num_pages -= cur_pages;
492
493 /* pages are in Y direction - height
494 page width in X direction - width */
495 radeon_ring_write(rdev, PACKET3(PACKET3_BITBLT_MULTI, 8));
496 radeon_ring_write(rdev,
497 RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
498 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
499 RADEON_GMC_SRC_CLIPPING |
500 RADEON_GMC_DST_CLIPPING |
501 RADEON_GMC_BRUSH_NONE |
502 (RADEON_COLOR_FORMAT_ARGB8888 << 8) |
503 RADEON_GMC_SRC_DATATYPE_COLOR |
504 RADEON_ROP3_S |
505 RADEON_DP_SRC_SOURCE_MEMORY |
506 RADEON_GMC_CLR_CMP_CNTL_DIS |
507 RADEON_GMC_WR_MSK_DIS);
508 radeon_ring_write(rdev, (pitch << 22) | (src_offset >> 10));
509 radeon_ring_write(rdev, (pitch << 22) | (dst_offset >> 10));
510 radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
511 radeon_ring_write(rdev, 0);
512 radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16));
513 radeon_ring_write(rdev, num_pages);
514 radeon_ring_write(rdev, num_pages);
515 radeon_ring_write(rdev, cur_pages | (stride_pixels << 16));
516 }
517 radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0));
518 radeon_ring_write(rdev, RADEON_RB2D_DC_FLUSH_ALL);
519 radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0));
520 radeon_ring_write(rdev,
521 RADEON_WAIT_2D_IDLECLEAN |
522 RADEON_WAIT_HOST_IDLECLEAN |
523 RADEON_WAIT_DMA_GUI_IDLE);
524 if (fence) {
525 r = radeon_fence_emit(rdev, fence);
526 }
527 radeon_ring_unlock_commit(rdev);
528 return r;
529}
530
Jerome Glisse45600232009-09-09 22:23:45 +0200531static int r100_cp_wait_for_idle(struct radeon_device *rdev)
532{
533 unsigned i;
534 u32 tmp;
535
536 for (i = 0; i < rdev->usec_timeout; i++) {
537 tmp = RREG32(R_000E40_RBBM_STATUS);
538 if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) {
539 return 0;
540 }
541 udelay(1);
542 }
543 return -1;
544}
545
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200546void r100_ring_start(struct radeon_device *rdev)
547{
548 int r;
549
550 r = radeon_ring_lock(rdev, 2);
551 if (r) {
552 return;
553 }
554 radeon_ring_write(rdev, PACKET0(RADEON_ISYNC_CNTL, 0));
555 radeon_ring_write(rdev,
556 RADEON_ISYNC_ANY2D_IDLE3D |
557 RADEON_ISYNC_ANY3D_IDLE2D |
558 RADEON_ISYNC_WAIT_IDLEGUI |
559 RADEON_ISYNC_CPSCRATCH_IDLEGUI);
560 radeon_ring_unlock_commit(rdev);
561}
562
Ben Hutchings70967ab2009-08-29 14:53:51 +0100563
564/* Load the microcode for the CP */
565static int r100_cp_init_microcode(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200566{
Ben Hutchings70967ab2009-08-29 14:53:51 +0100567 struct platform_device *pdev;
568 const char *fw_name = NULL;
569 int err;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200570
Ben Hutchings70967ab2009-08-29 14:53:51 +0100571 DRM_DEBUG("\n");
572
573 pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
574 err = IS_ERR(pdev);
575 if (err) {
576 printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
577 return -EINVAL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200578 }
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200579 if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
580 (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
581 (rdev->family == CHIP_RS200)) {
582 DRM_INFO("Loading R100 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100583 fw_name = FIRMWARE_R100;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200584 } else if ((rdev->family == CHIP_R200) ||
585 (rdev->family == CHIP_RV250) ||
586 (rdev->family == CHIP_RV280) ||
587 (rdev->family == CHIP_RS300)) {
588 DRM_INFO("Loading R200 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100589 fw_name = FIRMWARE_R200;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200590 } else if ((rdev->family == CHIP_R300) ||
591 (rdev->family == CHIP_R350) ||
592 (rdev->family == CHIP_RV350) ||
593 (rdev->family == CHIP_RV380) ||
594 (rdev->family == CHIP_RS400) ||
595 (rdev->family == CHIP_RS480)) {
596 DRM_INFO("Loading R300 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100597 fw_name = FIRMWARE_R300;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200598 } else if ((rdev->family == CHIP_R420) ||
599 (rdev->family == CHIP_R423) ||
600 (rdev->family == CHIP_RV410)) {
601 DRM_INFO("Loading R400 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100602 fw_name = FIRMWARE_R420;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200603 } else if ((rdev->family == CHIP_RS690) ||
604 (rdev->family == CHIP_RS740)) {
605 DRM_INFO("Loading RS690/RS740 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100606 fw_name = FIRMWARE_RS690;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200607 } else if (rdev->family == CHIP_RS600) {
608 DRM_INFO("Loading RS600 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100609 fw_name = FIRMWARE_RS600;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200610 } else if ((rdev->family == CHIP_RV515) ||
611 (rdev->family == CHIP_R520) ||
612 (rdev->family == CHIP_RV530) ||
613 (rdev->family == CHIP_R580) ||
614 (rdev->family == CHIP_RV560) ||
615 (rdev->family == CHIP_RV570)) {
616 DRM_INFO("Loading R500 Microcode\n");
Ben Hutchings70967ab2009-08-29 14:53:51 +0100617 fw_name = FIRMWARE_R520;
618 }
619
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000620 err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
Ben Hutchings70967ab2009-08-29 14:53:51 +0100621 platform_device_unregister(pdev);
622 if (err) {
623 printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n",
624 fw_name);
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000625 } else if (rdev->me_fw->size % 8) {
Ben Hutchings70967ab2009-08-29 14:53:51 +0100626 printk(KERN_ERR
627 "radeon_cp: Bogus length %zu in firmware \"%s\"\n",
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000628 rdev->me_fw->size, fw_name);
Ben Hutchings70967ab2009-08-29 14:53:51 +0100629 err = -EINVAL;
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000630 release_firmware(rdev->me_fw);
631 rdev->me_fw = NULL;
Ben Hutchings70967ab2009-08-29 14:53:51 +0100632 }
633 return err;
634}
Jerome Glissed4550902009-10-01 10:12:06 +0200635
Ben Hutchings70967ab2009-08-29 14:53:51 +0100636static void r100_cp_load_microcode(struct radeon_device *rdev)
637{
638 const __be32 *fw_data;
639 int i, size;
640
641 if (r100_gui_wait_for_idle(rdev)) {
642 printk(KERN_WARNING "Failed to wait GUI idle while "
643 "programming pipes. Bad things might happen.\n");
644 }
645
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000646 if (rdev->me_fw) {
647 size = rdev->me_fw->size / 4;
648 fw_data = (const __be32 *)&rdev->me_fw->data[0];
Ben Hutchings70967ab2009-08-29 14:53:51 +0100649 WREG32(RADEON_CP_ME_RAM_ADDR, 0);
650 for (i = 0; i < size; i += 2) {
651 WREG32(RADEON_CP_ME_RAM_DATAH,
652 be32_to_cpup(&fw_data[i]));
653 WREG32(RADEON_CP_ME_RAM_DATAL,
654 be32_to_cpup(&fw_data[i + 1]));
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200655 }
656 }
657}
658
659int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
660{
661 unsigned rb_bufsz;
662 unsigned rb_blksz;
663 unsigned max_fetch;
664 unsigned pre_write_timer;
665 unsigned pre_write_limit;
666 unsigned indirect2_start;
667 unsigned indirect1_start;
668 uint32_t tmp;
669 int r;
670
671 if (r100_debugfs_cp_init(rdev)) {
672 DRM_ERROR("Failed to register debugfs file for CP !\n");
673 }
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000674 if (!rdev->me_fw) {
Ben Hutchings70967ab2009-08-29 14:53:51 +0100675 r = r100_cp_init_microcode(rdev);
676 if (r) {
677 DRM_ERROR("Failed to load firmware!\n");
678 return r;
679 }
680 }
681
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200682 /* Align ring size */
683 rb_bufsz = drm_order(ring_size / 8);
684 ring_size = (1 << (rb_bufsz + 1)) * 4;
685 r100_cp_load_microcode(rdev);
686 r = radeon_ring_init(rdev, ring_size);
687 if (r) {
688 return r;
689 }
690 /* Each time the cp read 1024 bytes (16 dword/quadword) update
691 * the rptr copy in system ram */
692 rb_blksz = 9;
693 /* cp will read 128bytes at a time (4 dwords) */
694 max_fetch = 1;
695 rdev->cp.align_mask = 16 - 1;
696 /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */
697 pre_write_timer = 64;
698 /* Force CP_RB_WPTR write if written more than one time before the
699 * delay expire
700 */
701 pre_write_limit = 0;
702 /* Setup the cp cache like this (cache size is 96 dwords) :
703 * RING 0 to 15
704 * INDIRECT1 16 to 79
705 * INDIRECT2 80 to 95
706 * So ring cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords))
707 * indirect1 cache size is 64dwords (> (2 * max_fetch = 2 * 4dwords))
708 * indirect2 cache size is 16dwords (> (2 * max_fetch = 2 * 4dwords))
709 * Idea being that most of the gpu cmd will be through indirect1 buffer
710 * so it gets the bigger cache.
711 */
712 indirect2_start = 80;
713 indirect1_start = 16;
714 /* cp setup */
715 WREG32(0x718, pre_write_timer | (pre_write_limit << 28));
Alex Deucherd6f28932009-11-02 16:01:27 -0500716 tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) |
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200717 REG_SET(RADEON_RB_BLKSZ, rb_blksz) |
718 REG_SET(RADEON_MAX_FETCH, max_fetch) |
719 RADEON_RB_NO_UPDATE);
Alex Deucherd6f28932009-11-02 16:01:27 -0500720#ifdef __BIG_ENDIAN
721 tmp |= RADEON_BUF_SWAP_32BIT;
722#endif
723 WREG32(RADEON_CP_RB_CNTL, tmp);
724
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200725 /* Set ring address */
726 DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr);
727 WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr);
728 /* Force read & write ptr to 0 */
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200729 WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
730 WREG32(RADEON_CP_RB_RPTR_WR, 0);
731 WREG32(RADEON_CP_RB_WPTR, 0);
732 WREG32(RADEON_CP_RB_CNTL, tmp);
733 udelay(10);
734 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
735 rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
Dave Airlie9e5786b2010-03-31 13:38:56 +1000736 /* protect against crazy HW on resume */
737 rdev->cp.wptr &= rdev->cp.ptr_mask;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200738 /* Set cp mode to bus mastering & enable cp*/
739 WREG32(RADEON_CP_CSQ_MODE,
740 REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
741 REG_SET(RADEON_INDIRECT1_START, indirect1_start));
742 WREG32(0x718, 0);
743 WREG32(0x744, 0x00004D4D);
744 WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
745 radeon_ring_start(rdev);
746 r = radeon_ring_test(rdev);
747 if (r) {
748 DRM_ERROR("radeon: cp isn't working (%d).\n", r);
749 return r;
750 }
751 rdev->cp.ready = true;
752 return 0;
753}
754
755void r100_cp_fini(struct radeon_device *rdev)
756{
Jerome Glisse45600232009-09-09 22:23:45 +0200757 if (r100_cp_wait_for_idle(rdev)) {
758 DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n");
759 }
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200760 /* Disable ring */
Jerome Glissea18d7ea2009-09-09 22:23:27 +0200761 r100_cp_disable(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200762 radeon_ring_fini(rdev);
763 DRM_INFO("radeon: cp finalized\n");
764}
765
766void r100_cp_disable(struct radeon_device *rdev)
767{
768 /* Disable ring */
769 rdev->cp.ready = false;
770 WREG32(RADEON_CP_CSQ_MODE, 0);
771 WREG32(RADEON_CP_CSQ_CNTL, 0);
772 if (r100_gui_wait_for_idle(rdev)) {
773 printk(KERN_WARNING "Failed to wait GUI idle while "
774 "programming pipes. Bad things might happen.\n");
775 }
776}
777
Jerome Glisse3ce0a232009-09-08 10:10:24 +1000778void r100_cp_commit(struct radeon_device *rdev)
779{
780 WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr);
781 (void)RREG32(RADEON_CP_RB_WPTR);
782}
783
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200784
785/*
786 * CS functions
787 */
788int r100_cs_parse_packet0(struct radeon_cs_parser *p,
789 struct radeon_cs_packet *pkt,
Jerome Glisse068a1172009-06-17 13:28:30 +0200790 const unsigned *auth, unsigned n,
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200791 radeon_packet0_check_t check)
792{
793 unsigned reg;
794 unsigned i, j, m;
795 unsigned idx;
796 int r;
797
798 idx = pkt->idx + 1;
799 reg = pkt->reg;
Jerome Glisse068a1172009-06-17 13:28:30 +0200800 /* Check that register fall into register range
801 * determined by the number of entry (n) in the
802 * safe register bitmap.
803 */
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200804 if (pkt->one_reg_wr) {
805 if ((reg >> 7) > n) {
806 return -EINVAL;
807 }
808 } else {
809 if (((reg + (pkt->count << 2)) >> 7) > n) {
810 return -EINVAL;
811 }
812 }
813 for (i = 0; i <= pkt->count; i++, idx++) {
814 j = (reg >> 7);
815 m = 1 << ((reg >> 2) & 31);
816 if (auth[j] & m) {
817 r = check(p, pkt, idx, reg);
818 if (r) {
819 return r;
820 }
821 }
822 if (pkt->one_reg_wr) {
823 if (!(auth[j] & m)) {
824 break;
825 }
826 } else {
827 reg += 4;
828 }
829 }
830 return 0;
831}
832
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200833void r100_cs_dump_packet(struct radeon_cs_parser *p,
834 struct radeon_cs_packet *pkt)
835{
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200836 volatile uint32_t *ib;
837 unsigned i;
838 unsigned idx;
839
840 ib = p->ib->ptr;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200841 idx = pkt->idx;
842 for (i = 0; i <= (pkt->count + 1); i++, idx++) {
843 DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]);
844 }
845}
846
847/**
848 * r100_cs_packet_parse() - parse cp packet and point ib index to next packet
849 * @parser: parser structure holding parsing context.
850 * @pkt: where to store packet informations
851 *
852 * Assume that chunk_ib_index is properly set. Will return -EINVAL
853 * if packet is bigger than remaining ib size. or if packets is unknown.
854 **/
855int r100_cs_packet_parse(struct radeon_cs_parser *p,
856 struct radeon_cs_packet *pkt,
857 unsigned idx)
858{
859 struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx];
Roel Kluinfa992392009-08-03 14:20:32 +0200860 uint32_t header;
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200861
862 if (idx >= ib_chunk->length_dw) {
863 DRM_ERROR("Can not parse packet at %d after CS end %d !\n",
864 idx, ib_chunk->length_dw);
865 return -EINVAL;
866 }
Dave Airlie513bcb42009-09-23 16:56:27 +1000867 header = radeon_get_ib_value(p, idx);
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200868 pkt->idx = idx;
869 pkt->type = CP_PACKET_GET_TYPE(header);
870 pkt->count = CP_PACKET_GET_COUNT(header);
871 switch (pkt->type) {
872 case PACKET_TYPE0:
873 pkt->reg = CP_PACKET0_GET_REG(header);
874 pkt->one_reg_wr = CP_PACKET0_GET_ONE_REG_WR(header);
875 break;
876 case PACKET_TYPE3:
877 pkt->opcode = CP_PACKET3_GET_OPCODE(header);
878 break;
879 case PACKET_TYPE2:
880 pkt->count = -1;
881 break;
882 default:
883 DRM_ERROR("Unknown packet type %d at %d !\n", pkt->type, idx);
884 return -EINVAL;
885 }
886 if ((pkt->count + 1 + pkt->idx) >= ib_chunk->length_dw) {
887 DRM_ERROR("Packet (%d:%d:%d) end after CS buffer (%d) !\n",
888 pkt->idx, pkt->type, pkt->count, ib_chunk->length_dw);
889 return -EINVAL;
890 }
891 return 0;
892}
893
894/**
Dave Airlie531369e2009-06-29 11:21:25 +1000895 * r100_cs_packet_next_vline() - parse userspace VLINE packet
896 * @parser: parser structure holding parsing context.
897 *
898 * Userspace sends a special sequence for VLINE waits.
899 * PACKET0 - VLINE_START_END + value
900 * PACKET0 - WAIT_UNTIL +_value
901 * RELOC (P3) - crtc_id in reloc.
902 *
903 * This function parses this and relocates the VLINE START END
904 * and WAIT UNTIL packets to the correct crtc.
905 * It also detects a switched off crtc and nulls out the
906 * wait in that case.
907 */
908int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
909{
Dave Airlie531369e2009-06-29 11:21:25 +1000910 struct drm_mode_object *obj;
911 struct drm_crtc *crtc;
912 struct radeon_crtc *radeon_crtc;
913 struct radeon_cs_packet p3reloc, waitreloc;
914 int crtc_id;
915 int r;
916 uint32_t header, h_idx, reg;
Dave Airlie513bcb42009-09-23 16:56:27 +1000917 volatile uint32_t *ib;
Dave Airlie531369e2009-06-29 11:21:25 +1000918
Dave Airlie513bcb42009-09-23 16:56:27 +1000919 ib = p->ib->ptr;
Dave Airlie531369e2009-06-29 11:21:25 +1000920
921 /* parse the wait until */
922 r = r100_cs_packet_parse(p, &waitreloc, p->idx);
923 if (r)
924 return r;
925
926 /* check its a wait until and only 1 count */
927 if (waitreloc.reg != RADEON_WAIT_UNTIL ||
928 waitreloc.count != 0) {
929 DRM_ERROR("vline wait had illegal wait until segment\n");
930 r = -EINVAL;
931 return r;
932 }
933
Dave Airlie513bcb42009-09-23 16:56:27 +1000934 if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) {
Dave Airlie531369e2009-06-29 11:21:25 +1000935 DRM_ERROR("vline wait had illegal wait until\n");
936 r = -EINVAL;
937 return r;
938 }
939
940 /* jump over the NOP */
Alex Deucher90ebd062009-09-25 16:39:24 -0400941 r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2);
Dave Airlie531369e2009-06-29 11:21:25 +1000942 if (r)
943 return r;
944
945 h_idx = p->idx - 2;
Alex Deucher90ebd062009-09-25 16:39:24 -0400946 p->idx += waitreloc.count + 2;
947 p->idx += p3reloc.count + 2;
Dave Airlie531369e2009-06-29 11:21:25 +1000948
Dave Airlie513bcb42009-09-23 16:56:27 +1000949 header = radeon_get_ib_value(p, h_idx);
950 crtc_id = radeon_get_ib_value(p, h_idx + 5);
Dave Airlied4ac6a02009-10-08 11:32:49 +1000951 reg = CP_PACKET0_GET_REG(header);
Dave Airlie531369e2009-06-29 11:21:25 +1000952 mutex_lock(&p->rdev->ddev->mode_config.mutex);
953 obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
954 if (!obj) {
955 DRM_ERROR("cannot find crtc %d\n", crtc_id);
956 r = -EINVAL;
957 goto out;
958 }
959 crtc = obj_to_crtc(obj);
960 radeon_crtc = to_radeon_crtc(crtc);
961 crtc_id = radeon_crtc->crtc_id;
962
963 if (!crtc->enabled) {
964 /* if the CRTC isn't enabled - we need to nop out the wait until */
Dave Airlie513bcb42009-09-23 16:56:27 +1000965 ib[h_idx + 2] = PACKET2(0);
966 ib[h_idx + 3] = PACKET2(0);
Dave Airlie531369e2009-06-29 11:21:25 +1000967 } else if (crtc_id == 1) {
968 switch (reg) {
969 case AVIVO_D1MODE_VLINE_START_END:
Alex Deucher90ebd062009-09-25 16:39:24 -0400970 header &= ~R300_CP_PACKET0_REG_MASK;
Dave Airlie531369e2009-06-29 11:21:25 +1000971 header |= AVIVO_D2MODE_VLINE_START_END >> 2;
972 break;
973 case RADEON_CRTC_GUI_TRIG_VLINE:
Alex Deucher90ebd062009-09-25 16:39:24 -0400974 header &= ~R300_CP_PACKET0_REG_MASK;
Dave Airlie531369e2009-06-29 11:21:25 +1000975 header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2;
976 break;
977 default:
978 DRM_ERROR("unknown crtc reloc\n");
979 r = -EINVAL;
980 goto out;
981 }
Dave Airlie513bcb42009-09-23 16:56:27 +1000982 ib[h_idx] = header;
983 ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1;
Dave Airlie531369e2009-06-29 11:21:25 +1000984 }
985out:
986 mutex_unlock(&p->rdev->ddev->mode_config.mutex);
987 return r;
988}
989
990/**
Jerome Glisse771fe6b2009-06-05 14:42:42 +0200991 * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3
992 * @parser: parser structure holding parsing context.
993 * @data: pointer to relocation data
994 * @offset_start: starting offset
995 * @offset_mask: offset mask (to align start offset on)
996 * @reloc: reloc informations
997 *
998 * Check next packet is relocation packet3, do bo validation and compute
999 * GPU offset using the provided start.
1000 **/
1001int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
1002 struct radeon_cs_reloc **cs_reloc)
1003{
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001004 struct radeon_cs_chunk *relocs_chunk;
1005 struct radeon_cs_packet p3reloc;
1006 unsigned idx;
1007 int r;
1008
1009 if (p->chunk_relocs_idx == -1) {
1010 DRM_ERROR("No relocation chunk !\n");
1011 return -EINVAL;
1012 }
1013 *cs_reloc = NULL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001014 relocs_chunk = &p->chunks[p->chunk_relocs_idx];
1015 r = r100_cs_packet_parse(p, &p3reloc, p->idx);
1016 if (r) {
1017 return r;
1018 }
1019 p->idx += p3reloc.count + 2;
1020 if (p3reloc.type != PACKET_TYPE3 || p3reloc.opcode != PACKET3_NOP) {
1021 DRM_ERROR("No packet3 for relocation for packet at %d.\n",
1022 p3reloc.idx);
1023 r100_cs_dump_packet(p, &p3reloc);
1024 return -EINVAL;
1025 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001026 idx = radeon_get_ib_value(p, p3reloc.idx + 1);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001027 if (idx >= relocs_chunk->length_dw) {
1028 DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
1029 idx, relocs_chunk->length_dw);
1030 r100_cs_dump_packet(p, &p3reloc);
1031 return -EINVAL;
1032 }
1033 /* FIXME: we assume reloc size is 4 dwords */
1034 *cs_reloc = p->relocs_ptr[(idx / 4)];
1035 return 0;
1036}
1037
Dave Airlie551ebd82009-09-01 15:25:57 +10001038static int r100_get_vtx_size(uint32_t vtx_fmt)
1039{
1040 int vtx_size;
1041 vtx_size = 2;
1042 /* ordered according to bits in spec */
1043 if (vtx_fmt & RADEON_SE_VTX_FMT_W0)
1044 vtx_size++;
1045 if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR)
1046 vtx_size += 3;
1047 if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA)
1048 vtx_size++;
1049 if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR)
1050 vtx_size++;
1051 if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC)
1052 vtx_size += 3;
1053 if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG)
1054 vtx_size++;
1055 if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC)
1056 vtx_size++;
1057 if (vtx_fmt & RADEON_SE_VTX_FMT_ST0)
1058 vtx_size += 2;
1059 if (vtx_fmt & RADEON_SE_VTX_FMT_ST1)
1060 vtx_size += 2;
1061 if (vtx_fmt & RADEON_SE_VTX_FMT_Q1)
1062 vtx_size++;
1063 if (vtx_fmt & RADEON_SE_VTX_FMT_ST2)
1064 vtx_size += 2;
1065 if (vtx_fmt & RADEON_SE_VTX_FMT_Q2)
1066 vtx_size++;
1067 if (vtx_fmt & RADEON_SE_VTX_FMT_ST3)
1068 vtx_size += 2;
1069 if (vtx_fmt & RADEON_SE_VTX_FMT_Q3)
1070 vtx_size++;
1071 if (vtx_fmt & RADEON_SE_VTX_FMT_Q0)
1072 vtx_size++;
1073 /* blend weight */
1074 if (vtx_fmt & (0x7 << 15))
1075 vtx_size += (vtx_fmt >> 15) & 0x7;
1076 if (vtx_fmt & RADEON_SE_VTX_FMT_N0)
1077 vtx_size += 3;
1078 if (vtx_fmt & RADEON_SE_VTX_FMT_XY1)
1079 vtx_size += 2;
1080 if (vtx_fmt & RADEON_SE_VTX_FMT_Z1)
1081 vtx_size++;
1082 if (vtx_fmt & RADEON_SE_VTX_FMT_W1)
1083 vtx_size++;
1084 if (vtx_fmt & RADEON_SE_VTX_FMT_N1)
1085 vtx_size++;
1086 if (vtx_fmt & RADEON_SE_VTX_FMT_Z)
1087 vtx_size++;
1088 return vtx_size;
1089}
1090
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001091static int r100_packet0_check(struct radeon_cs_parser *p,
Dave Airlie551ebd82009-09-01 15:25:57 +10001092 struct radeon_cs_packet *pkt,
1093 unsigned idx, unsigned reg)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001094{
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001095 struct radeon_cs_reloc *reloc;
Dave Airlie551ebd82009-09-01 15:25:57 +10001096 struct r100_cs_track *track;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001097 volatile uint32_t *ib;
1098 uint32_t tmp;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001099 int r;
Dave Airlie551ebd82009-09-01 15:25:57 +10001100 int i, face;
Dave Airliee024e112009-06-24 09:48:08 +10001101 u32 tile_flags = 0;
Dave Airlie513bcb42009-09-23 16:56:27 +10001102 u32 idx_value;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001103
1104 ib = p->ib->ptr;
Dave Airlie551ebd82009-09-01 15:25:57 +10001105 track = (struct r100_cs_track *)p->track;
1106
Dave Airlie513bcb42009-09-23 16:56:27 +10001107 idx_value = radeon_get_ib_value(p, idx);
1108
Dave Airlie551ebd82009-09-01 15:25:57 +10001109 switch (reg) {
1110 case RADEON_CRTC_GUI_TRIG_VLINE:
1111 r = r100_cs_packet_parse_vline(p);
1112 if (r) {
1113 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1114 idx, reg);
1115 r100_cs_dump_packet(p, pkt);
1116 return r;
1117 }
1118 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001119 /* FIXME: only allow PACKET3 blit? easier to check for out of
1120 * range access */
Dave Airlie551ebd82009-09-01 15:25:57 +10001121 case RADEON_DST_PITCH_OFFSET:
1122 case RADEON_SRC_PITCH_OFFSET:
1123 r = r100_reloc_pitch_offset(p, pkt, idx, reg);
1124 if (r)
1125 return r;
1126 break;
1127 case RADEON_RB3D_DEPTHOFFSET:
1128 r = r100_cs_packet_next_reloc(p, &reloc);
1129 if (r) {
1130 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1131 idx, reg);
1132 r100_cs_dump_packet(p, pkt);
1133 return r;
1134 }
1135 track->zb.robj = reloc->robj;
Dave Airlie513bcb42009-09-23 16:56:27 +10001136 track->zb.offset = idx_value;
1137 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001138 break;
1139 case RADEON_RB3D_COLOROFFSET:
1140 r = r100_cs_packet_next_reloc(p, &reloc);
1141 if (r) {
1142 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1143 idx, reg);
1144 r100_cs_dump_packet(p, pkt);
1145 return r;
1146 }
1147 track->cb[0].robj = reloc->robj;
Dave Airlie513bcb42009-09-23 16:56:27 +10001148 track->cb[0].offset = idx_value;
1149 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001150 break;
1151 case RADEON_PP_TXOFFSET_0:
1152 case RADEON_PP_TXOFFSET_1:
1153 case RADEON_PP_TXOFFSET_2:
1154 i = (reg - RADEON_PP_TXOFFSET_0) / 24;
1155 r = r100_cs_packet_next_reloc(p, &reloc);
1156 if (r) {
1157 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1158 idx, reg);
1159 r100_cs_dump_packet(p, pkt);
1160 return r;
1161 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001162 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001163 track->textures[i].robj = reloc->robj;
1164 break;
1165 case RADEON_PP_CUBIC_OFFSET_T0_0:
1166 case RADEON_PP_CUBIC_OFFSET_T0_1:
1167 case RADEON_PP_CUBIC_OFFSET_T0_2:
1168 case RADEON_PP_CUBIC_OFFSET_T0_3:
1169 case RADEON_PP_CUBIC_OFFSET_T0_4:
1170 i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4;
1171 r = r100_cs_packet_next_reloc(p, &reloc);
1172 if (r) {
1173 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1174 idx, reg);
1175 r100_cs_dump_packet(p, pkt);
1176 return r;
1177 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001178 track->textures[0].cube_info[i].offset = idx_value;
1179 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001180 track->textures[0].cube_info[i].robj = reloc->robj;
1181 break;
1182 case RADEON_PP_CUBIC_OFFSET_T1_0:
1183 case RADEON_PP_CUBIC_OFFSET_T1_1:
1184 case RADEON_PP_CUBIC_OFFSET_T1_2:
1185 case RADEON_PP_CUBIC_OFFSET_T1_3:
1186 case RADEON_PP_CUBIC_OFFSET_T1_4:
1187 i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4;
1188 r = r100_cs_packet_next_reloc(p, &reloc);
1189 if (r) {
1190 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1191 idx, reg);
1192 r100_cs_dump_packet(p, pkt);
1193 return r;
1194 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001195 track->textures[1].cube_info[i].offset = idx_value;
1196 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001197 track->textures[1].cube_info[i].robj = reloc->robj;
1198 break;
1199 case RADEON_PP_CUBIC_OFFSET_T2_0:
1200 case RADEON_PP_CUBIC_OFFSET_T2_1:
1201 case RADEON_PP_CUBIC_OFFSET_T2_2:
1202 case RADEON_PP_CUBIC_OFFSET_T2_3:
1203 case RADEON_PP_CUBIC_OFFSET_T2_4:
1204 i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4;
1205 r = r100_cs_packet_next_reloc(p, &reloc);
1206 if (r) {
1207 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1208 idx, reg);
1209 r100_cs_dump_packet(p, pkt);
1210 return r;
1211 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001212 track->textures[2].cube_info[i].offset = idx_value;
1213 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001214 track->textures[2].cube_info[i].robj = reloc->robj;
1215 break;
1216 case RADEON_RE_WIDTH_HEIGHT:
Dave Airlie513bcb42009-09-23 16:56:27 +10001217 track->maxy = ((idx_value >> 16) & 0x7FF);
Dave Airlie551ebd82009-09-01 15:25:57 +10001218 break;
1219 case RADEON_RB3D_COLORPITCH:
1220 r = r100_cs_packet_next_reloc(p, &reloc);
1221 if (r) {
1222 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1223 idx, reg);
1224 r100_cs_dump_packet(p, pkt);
1225 return r;
1226 }
Dave Airliee024e112009-06-24 09:48:08 +10001227
Dave Airlie551ebd82009-09-01 15:25:57 +10001228 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1229 tile_flags |= RADEON_COLOR_TILE_ENABLE;
1230 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1231 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
Dave Airliee024e112009-06-24 09:48:08 +10001232
Dave Airlie513bcb42009-09-23 16:56:27 +10001233 tmp = idx_value & ~(0x7 << 16);
Dave Airlie551ebd82009-09-01 15:25:57 +10001234 tmp |= tile_flags;
1235 ib[idx] = tmp;
1236
Dave Airlie513bcb42009-09-23 16:56:27 +10001237 track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
Dave Airlie551ebd82009-09-01 15:25:57 +10001238 break;
1239 case RADEON_RB3D_DEPTHPITCH:
Dave Airlie513bcb42009-09-23 16:56:27 +10001240 track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
Dave Airlie551ebd82009-09-01 15:25:57 +10001241 break;
1242 case RADEON_RB3D_CNTL:
Dave Airlie513bcb42009-09-23 16:56:27 +10001243 switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001244 case 7:
1245 case 8:
1246 case 9:
1247 case 11:
1248 case 12:
1249 track->cb[0].cpp = 1;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001250 break;
Dave Airlie551ebd82009-09-01 15:25:57 +10001251 case 3:
1252 case 4:
1253 case 15:
1254 track->cb[0].cpp = 2;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001255 break;
Dave Airlie551ebd82009-09-01 15:25:57 +10001256 case 6:
1257 track->cb[0].cpp = 4;
Dave Airlie17782d92009-08-21 10:07:54 +10001258 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001259 default:
Dave Airlie551ebd82009-09-01 15:25:57 +10001260 DRM_ERROR("Invalid color buffer format (%d) !\n",
Dave Airlie513bcb42009-09-23 16:56:27 +10001261 ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
Dave Airlie551ebd82009-09-01 15:25:57 +10001262 return -EINVAL;
1263 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001264 track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
Dave Airlie551ebd82009-09-01 15:25:57 +10001265 break;
1266 case RADEON_RB3D_ZSTENCILCNTL:
Dave Airlie513bcb42009-09-23 16:56:27 +10001267 switch (idx_value & 0xf) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001268 case 0:
1269 track->zb.cpp = 2;
1270 break;
1271 case 2:
1272 case 3:
1273 case 4:
1274 case 5:
1275 case 9:
1276 case 11:
1277 track->zb.cpp = 4;
1278 break;
1279 default:
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001280 break;
1281 }
Dave Airlie551ebd82009-09-01 15:25:57 +10001282 break;
1283 case RADEON_RB3D_ZPASS_ADDR:
1284 r = r100_cs_packet_next_reloc(p, &reloc);
1285 if (r) {
1286 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1287 idx, reg);
1288 r100_cs_dump_packet(p, pkt);
1289 return r;
1290 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001291 ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001292 break;
1293 case RADEON_PP_CNTL:
1294 {
Dave Airlie513bcb42009-09-23 16:56:27 +10001295 uint32_t temp = idx_value >> 4;
Dave Airlie551ebd82009-09-01 15:25:57 +10001296 for (i = 0; i < track->num_texture; i++)
1297 track->textures[i].enabled = !!(temp & (1 << i));
1298 }
1299 break;
1300 case RADEON_SE_VF_CNTL:
Dave Airlie513bcb42009-09-23 16:56:27 +10001301 track->vap_vf_cntl = idx_value;
Dave Airlie551ebd82009-09-01 15:25:57 +10001302 break;
1303 case RADEON_SE_VTX_FMT:
Dave Airlie513bcb42009-09-23 16:56:27 +10001304 track->vtx_size = r100_get_vtx_size(idx_value);
Dave Airlie551ebd82009-09-01 15:25:57 +10001305 break;
1306 case RADEON_PP_TEX_SIZE_0:
1307 case RADEON_PP_TEX_SIZE_1:
1308 case RADEON_PP_TEX_SIZE_2:
1309 i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
Dave Airlie513bcb42009-09-23 16:56:27 +10001310 track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
1311 track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
Dave Airlie551ebd82009-09-01 15:25:57 +10001312 break;
1313 case RADEON_PP_TEX_PITCH_0:
1314 case RADEON_PP_TEX_PITCH_1:
1315 case RADEON_PP_TEX_PITCH_2:
1316 i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
Dave Airlie513bcb42009-09-23 16:56:27 +10001317 track->textures[i].pitch = idx_value + 32;
Dave Airlie551ebd82009-09-01 15:25:57 +10001318 break;
1319 case RADEON_PP_TXFILTER_0:
1320 case RADEON_PP_TXFILTER_1:
1321 case RADEON_PP_TXFILTER_2:
1322 i = (reg - RADEON_PP_TXFILTER_0) / 24;
Dave Airlie513bcb42009-09-23 16:56:27 +10001323 track->textures[i].num_levels = ((idx_value & RADEON_MAX_MIP_LEVEL_MASK)
Dave Airlie551ebd82009-09-01 15:25:57 +10001324 >> RADEON_MAX_MIP_LEVEL_SHIFT);
Dave Airlie513bcb42009-09-23 16:56:27 +10001325 tmp = (idx_value >> 23) & 0x7;
Dave Airlie551ebd82009-09-01 15:25:57 +10001326 if (tmp == 2 || tmp == 6)
1327 track->textures[i].roundup_w = false;
Dave Airlie513bcb42009-09-23 16:56:27 +10001328 tmp = (idx_value >> 27) & 0x7;
Dave Airlie551ebd82009-09-01 15:25:57 +10001329 if (tmp == 2 || tmp == 6)
1330 track->textures[i].roundup_h = false;
1331 break;
1332 case RADEON_PP_TXFORMAT_0:
1333 case RADEON_PP_TXFORMAT_1:
1334 case RADEON_PP_TXFORMAT_2:
1335 i = (reg - RADEON_PP_TXFORMAT_0) / 24;
Dave Airlie513bcb42009-09-23 16:56:27 +10001336 if (idx_value & RADEON_TXFORMAT_NON_POWER2) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001337 track->textures[i].use_pitch = 1;
1338 } else {
1339 track->textures[i].use_pitch = 0;
Dave Airlie513bcb42009-09-23 16:56:27 +10001340 track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
1341 track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
Dave Airlie551ebd82009-09-01 15:25:57 +10001342 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001343 if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
Dave Airlie551ebd82009-09-01 15:25:57 +10001344 track->textures[i].tex_coord_type = 2;
Dave Airlie513bcb42009-09-23 16:56:27 +10001345 switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001346 case RADEON_TXFORMAT_I8:
1347 case RADEON_TXFORMAT_RGB332:
1348 case RADEON_TXFORMAT_Y8:
1349 track->textures[i].cpp = 1;
1350 break;
1351 case RADEON_TXFORMAT_AI88:
1352 case RADEON_TXFORMAT_ARGB1555:
1353 case RADEON_TXFORMAT_RGB565:
1354 case RADEON_TXFORMAT_ARGB4444:
1355 case RADEON_TXFORMAT_VYUY422:
1356 case RADEON_TXFORMAT_YVYU422:
Dave Airlie551ebd82009-09-01 15:25:57 +10001357 case RADEON_TXFORMAT_SHADOW16:
1358 case RADEON_TXFORMAT_LDUDV655:
1359 case RADEON_TXFORMAT_DUDV88:
1360 track->textures[i].cpp = 2;
1361 break;
1362 case RADEON_TXFORMAT_ARGB8888:
1363 case RADEON_TXFORMAT_RGBA8888:
Dave Airlie551ebd82009-09-01 15:25:57 +10001364 case RADEON_TXFORMAT_SHADOW32:
1365 case RADEON_TXFORMAT_LDUDUV8888:
1366 track->textures[i].cpp = 4;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001367 break;
Dave Airlied785d782009-12-07 13:16:06 +10001368 case RADEON_TXFORMAT_DXT1:
1369 track->textures[i].cpp = 1;
1370 track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
1371 break;
1372 case RADEON_TXFORMAT_DXT23:
1373 case RADEON_TXFORMAT_DXT45:
1374 track->textures[i].cpp = 1;
1375 track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
1376 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001377 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001378 track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
1379 track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
Dave Airlie551ebd82009-09-01 15:25:57 +10001380 break;
1381 case RADEON_PP_CUBIC_FACES_0:
1382 case RADEON_PP_CUBIC_FACES_1:
1383 case RADEON_PP_CUBIC_FACES_2:
Dave Airlie513bcb42009-09-23 16:56:27 +10001384 tmp = idx_value;
Dave Airlie551ebd82009-09-01 15:25:57 +10001385 i = (reg - RADEON_PP_CUBIC_FACES_0) / 4;
1386 for (face = 0; face < 4; face++) {
1387 track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
1388 track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf);
1389 }
1390 break;
1391 default:
1392 printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
1393 reg, idx);
1394 return -EINVAL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001395 }
1396 return 0;
1397}
1398
Jerome Glisse068a1172009-06-17 13:28:30 +02001399int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
1400 struct radeon_cs_packet *pkt,
Jerome Glisse4c788672009-11-20 14:29:23 +01001401 struct radeon_bo *robj)
Jerome Glisse068a1172009-06-17 13:28:30 +02001402{
Jerome Glisse068a1172009-06-17 13:28:30 +02001403 unsigned idx;
Dave Airlie513bcb42009-09-23 16:56:27 +10001404 u32 value;
Jerome Glisse068a1172009-06-17 13:28:30 +02001405 idx = pkt->idx + 1;
Dave Airlie513bcb42009-09-23 16:56:27 +10001406 value = radeon_get_ib_value(p, idx + 2);
Jerome Glisse4c788672009-11-20 14:29:23 +01001407 if ((value + 1) > radeon_bo_size(robj)) {
Jerome Glisse068a1172009-06-17 13:28:30 +02001408 DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
1409 "(need %u have %lu) !\n",
Dave Airlie513bcb42009-09-23 16:56:27 +10001410 value + 1,
Jerome Glisse4c788672009-11-20 14:29:23 +01001411 radeon_bo_size(robj));
Jerome Glisse068a1172009-06-17 13:28:30 +02001412 return -EINVAL;
1413 }
1414 return 0;
1415}
1416
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001417static int r100_packet3_check(struct radeon_cs_parser *p,
1418 struct radeon_cs_packet *pkt)
1419{
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001420 struct radeon_cs_reloc *reloc;
Dave Airlie551ebd82009-09-01 15:25:57 +10001421 struct r100_cs_track *track;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001422 unsigned idx;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001423 volatile uint32_t *ib;
1424 int r;
1425
1426 ib = p->ib->ptr;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001427 idx = pkt->idx + 1;
Dave Airlie551ebd82009-09-01 15:25:57 +10001428 track = (struct r100_cs_track *)p->track;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001429 switch (pkt->opcode) {
1430 case PACKET3_3D_LOAD_VBPNTR:
Dave Airlie513bcb42009-09-23 16:56:27 +10001431 r = r100_packet3_load_vbpntr(p, pkt, idx);
1432 if (r)
1433 return r;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001434 break;
1435 case PACKET3_INDX_BUFFER:
1436 r = r100_cs_packet_next_reloc(p, &reloc);
1437 if (r) {
1438 DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode);
1439 r100_cs_dump_packet(p, pkt);
1440 return r;
1441 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001442 ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset);
Jerome Glisse068a1172009-06-17 13:28:30 +02001443 r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj);
1444 if (r) {
1445 return r;
1446 }
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001447 break;
1448 case 0x23:
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001449 /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */
1450 r = r100_cs_packet_next_reloc(p, &reloc);
1451 if (r) {
1452 DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode);
1453 r100_cs_dump_packet(p, pkt);
1454 return r;
1455 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001456 ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset);
Dave Airlie551ebd82009-09-01 15:25:57 +10001457 track->num_arrays = 1;
Dave Airlie513bcb42009-09-23 16:56:27 +10001458 track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 2));
Dave Airlie551ebd82009-09-01 15:25:57 +10001459
1460 track->arrays[0].robj = reloc->robj;
1461 track->arrays[0].esize = track->vtx_size;
1462
Dave Airlie513bcb42009-09-23 16:56:27 +10001463 track->max_indx = radeon_get_ib_value(p, idx+1);
Dave Airlie551ebd82009-09-01 15:25:57 +10001464
Dave Airlie513bcb42009-09-23 16:56:27 +10001465 track->vap_vf_cntl = radeon_get_ib_value(p, idx+3);
Dave Airlie551ebd82009-09-01 15:25:57 +10001466 track->immd_dwords = pkt->count - 1;
1467 r = r100_cs_track_check(p->rdev, track);
1468 if (r)
1469 return r;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001470 break;
1471 case PACKET3_3D_DRAW_IMMD:
Dave Airlie513bcb42009-09-23 16:56:27 +10001472 if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001473 DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
1474 return -EINVAL;
1475 }
Alex Deuchercf57fc72010-01-18 20:20:07 -05001476 track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 0));
Dave Airlie513bcb42009-09-23 16:56:27 +10001477 track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
Dave Airlie551ebd82009-09-01 15:25:57 +10001478 track->immd_dwords = pkt->count - 1;
1479 r = r100_cs_track_check(p->rdev, track);
1480 if (r)
1481 return r;
1482 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001483 /* triggers drawing using in-packet vertex data */
1484 case PACKET3_3D_DRAW_IMMD_2:
Dave Airlie513bcb42009-09-23 16:56:27 +10001485 if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) {
Dave Airlie551ebd82009-09-01 15:25:57 +10001486 DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
1487 return -EINVAL;
1488 }
Dave Airlie513bcb42009-09-23 16:56:27 +10001489 track->vap_vf_cntl = radeon_get_ib_value(p, idx);
Dave Airlie551ebd82009-09-01 15:25:57 +10001490 track->immd_dwords = pkt->count;
1491 r = r100_cs_track_check(p->rdev, track);
1492 if (r)
1493 return r;
1494 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001495 /* triggers drawing using in-packet vertex data */
1496 case PACKET3_3D_DRAW_VBUF_2:
Dave Airlie513bcb42009-09-23 16:56:27 +10001497 track->vap_vf_cntl = radeon_get_ib_value(p, idx);
Dave Airlie551ebd82009-09-01 15:25:57 +10001498 r = r100_cs_track_check(p->rdev, track);
1499 if (r)
1500 return r;
1501 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001502 /* triggers drawing of vertex buffers setup elsewhere */
1503 case PACKET3_3D_DRAW_INDX_2:
Dave Airlie513bcb42009-09-23 16:56:27 +10001504 track->vap_vf_cntl = radeon_get_ib_value(p, idx);
Dave Airlie551ebd82009-09-01 15:25:57 +10001505 r = r100_cs_track_check(p->rdev, track);
1506 if (r)
1507 return r;
1508 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001509 /* triggers drawing using indices to vertex buffer */
1510 case PACKET3_3D_DRAW_VBUF:
Dave Airlie513bcb42009-09-23 16:56:27 +10001511 track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
Dave Airlie551ebd82009-09-01 15:25:57 +10001512 r = r100_cs_track_check(p->rdev, track);
1513 if (r)
1514 return r;
1515 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001516 /* triggers drawing of vertex buffers setup elsewhere */
1517 case PACKET3_3D_DRAW_INDX:
Dave Airlie513bcb42009-09-23 16:56:27 +10001518 track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
Dave Airlie551ebd82009-09-01 15:25:57 +10001519 r = r100_cs_track_check(p->rdev, track);
1520 if (r)
1521 return r;
1522 break;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001523 /* triggers drawing using indices to vertex buffer */
1524 case PACKET3_NOP:
1525 break;
1526 default:
1527 DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode);
1528 return -EINVAL;
1529 }
1530 return 0;
1531}
1532
1533int r100_cs_parse(struct radeon_cs_parser *p)
1534{
1535 struct radeon_cs_packet pkt;
Jerome Glisse9f022dd2009-09-11 15:35:22 +02001536 struct r100_cs_track *track;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001537 int r;
1538
Jerome Glisse9f022dd2009-09-11 15:35:22 +02001539 track = kzalloc(sizeof(*track), GFP_KERNEL);
1540 r100_cs_track_clear(p->rdev, track);
1541 p->track = track;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001542 do {
1543 r = r100_cs_packet_parse(p, &pkt, p->idx);
1544 if (r) {
1545 return r;
1546 }
1547 p->idx += pkt.count + 2;
1548 switch (pkt.type) {
Jerome Glisse068a1172009-06-17 13:28:30 +02001549 case PACKET_TYPE0:
Dave Airlie551ebd82009-09-01 15:25:57 +10001550 if (p->rdev->family >= CHIP_R200)
1551 r = r100_cs_parse_packet0(p, &pkt,
1552 p->rdev->config.r100.reg_safe_bm,
1553 p->rdev->config.r100.reg_safe_bm_size,
1554 &r200_packet0_check);
1555 else
1556 r = r100_cs_parse_packet0(p, &pkt,
1557 p->rdev->config.r100.reg_safe_bm,
1558 p->rdev->config.r100.reg_safe_bm_size,
1559 &r100_packet0_check);
Jerome Glisse068a1172009-06-17 13:28:30 +02001560 break;
1561 case PACKET_TYPE2:
1562 break;
1563 case PACKET_TYPE3:
1564 r = r100_packet3_check(p, &pkt);
1565 break;
1566 default:
1567 DRM_ERROR("Unknown packet type %d !\n",
1568 pkt.type);
1569 return -EINVAL;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001570 }
1571 if (r) {
1572 return r;
1573 }
1574 } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw);
1575 return 0;
1576}
1577
1578
1579/*
1580 * Global GPU functions
1581 */
1582void r100_errata(struct radeon_device *rdev)
1583{
1584 rdev->pll_errata = 0;
1585
1586 if (rdev->family == CHIP_RV200 || rdev->family == CHIP_RS200) {
1587 rdev->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS;
1588 }
1589
1590 if (rdev->family == CHIP_RV100 ||
1591 rdev->family == CHIP_RS100 ||
1592 rdev->family == CHIP_RS200) {
1593 rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY;
1594 }
1595}
1596
1597/* Wait for vertical sync on primary CRTC */
1598void r100_gpu_wait_for_vsync(struct radeon_device *rdev)
1599{
1600 uint32_t crtc_gen_cntl, tmp;
1601 int i;
1602
1603 crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL);
1604 if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
1605 !(crtc_gen_cntl & RADEON_CRTC_EN)) {
1606 return;
1607 }
1608 /* Clear the CRTC_VBLANK_SAVE bit */
1609 WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
1610 for (i = 0; i < rdev->usec_timeout; i++) {
1611 tmp = RREG32(RADEON_CRTC_STATUS);
1612 if (tmp & RADEON_CRTC_VBLANK_SAVE) {
1613 return;
1614 }
1615 DRM_UDELAY(1);
1616 }
1617}
1618
1619/* Wait for vertical sync on secondary CRTC */
1620void r100_gpu_wait_for_vsync2(struct radeon_device *rdev)
1621{
1622 uint32_t crtc2_gen_cntl, tmp;
1623 int i;
1624
1625 crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
1626 if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
1627 !(crtc2_gen_cntl & RADEON_CRTC2_EN))
1628 return;
1629
1630 /* Clear the CRTC_VBLANK_SAVE bit */
1631 WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
1632 for (i = 0; i < rdev->usec_timeout; i++) {
1633 tmp = RREG32(RADEON_CRTC2_STATUS);
1634 if (tmp & RADEON_CRTC2_VBLANK_SAVE) {
1635 return;
1636 }
1637 DRM_UDELAY(1);
1638 }
1639}
1640
1641int r100_rbbm_fifo_wait_for_entry(struct radeon_device *rdev, unsigned n)
1642{
1643 unsigned i;
1644 uint32_t tmp;
1645
1646 for (i = 0; i < rdev->usec_timeout; i++) {
1647 tmp = RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
1648 if (tmp >= n) {
1649 return 0;
1650 }
1651 DRM_UDELAY(1);
1652 }
1653 return -1;
1654}
1655
1656int r100_gui_wait_for_idle(struct radeon_device *rdev)
1657{
1658 unsigned i;
1659 uint32_t tmp;
1660
1661 if (r100_rbbm_fifo_wait_for_entry(rdev, 64)) {
1662 printk(KERN_WARNING "radeon: wait for empty RBBM fifo failed !"
1663 " Bad things might happen.\n");
1664 }
1665 for (i = 0; i < rdev->usec_timeout; i++) {
1666 tmp = RREG32(RADEON_RBBM_STATUS);
Alex Deucher4612dc92010-02-05 01:58:28 -05001667 if (!(tmp & RADEON_RBBM_ACTIVE)) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001668 return 0;
1669 }
1670 DRM_UDELAY(1);
1671 }
1672 return -1;
1673}
1674
1675int r100_mc_wait_for_idle(struct radeon_device *rdev)
1676{
1677 unsigned i;
1678 uint32_t tmp;
1679
1680 for (i = 0; i < rdev->usec_timeout; i++) {
1681 /* read MC_STATUS */
Alex Deucher4612dc92010-02-05 01:58:28 -05001682 tmp = RREG32(RADEON_MC_STATUS);
1683 if (tmp & RADEON_MC_IDLE) {
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001684 return 0;
1685 }
1686 DRM_UDELAY(1);
1687 }
1688 return -1;
1689}
1690
Jerome Glisse225758d2010-03-09 14:45:10 +00001691void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001692{
Jerome Glisse225758d2010-03-09 14:45:10 +00001693 lockup->last_cp_rptr = cp->rptr;
1694 lockup->last_jiffies = jiffies;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001695}
1696
Jerome Glisse225758d2010-03-09 14:45:10 +00001697/**
1698 * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information
1699 * @rdev: radeon device structure
1700 * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations
1701 * @cp: radeon_cp structure holding CP information
1702 *
1703 * We don't need to initialize the lockup tracking information as we will either
1704 * have CP rptr to a different value of jiffies wrap around which will force
1705 * initialization of the lockup tracking informations.
1706 *
1707 * A possible false positivie is if we get call after while and last_cp_rptr ==
1708 * the current CP rptr, even if it's unlikely it might happen. To avoid this
1709 * if the elapsed time since last call is bigger than 2 second than we return
1710 * false and update the tracking information. Due to this the caller must call
1711 * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported
1712 * the fencing code should be cautious about that.
1713 *
1714 * Caller should write to the ring to force CP to do something so we don't get
1715 * false positive when CP is just gived nothing to do.
1716 *
1717 **/
1718bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001719{
Jerome Glisse225758d2010-03-09 14:45:10 +00001720 unsigned long cjiffies, elapsed;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001721
Jerome Glisse225758d2010-03-09 14:45:10 +00001722 cjiffies = jiffies;
1723 if (!time_after(cjiffies, lockup->last_jiffies)) {
1724 /* likely a wrap around */
1725 lockup->last_cp_rptr = cp->rptr;
1726 lockup->last_jiffies = jiffies;
1727 return false;
1728 }
1729 if (cp->rptr != lockup->last_cp_rptr) {
1730 /* CP is still working no lockup */
1731 lockup->last_cp_rptr = cp->rptr;
1732 lockup->last_jiffies = jiffies;
1733 return false;
1734 }
1735 elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies);
1736 if (elapsed >= 3000) {
1737 /* very likely the improbable case where current
1738 * rptr is equal to last recorded, a while ago, rptr
1739 * this is more likely a false positive update tracking
1740 * information which should force us to be recall at
1741 * latter point
1742 */
1743 lockup->last_cp_rptr = cp->rptr;
1744 lockup->last_jiffies = jiffies;
1745 return false;
1746 }
1747 if (elapsed >= 1000) {
1748 dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed);
1749 return true;
1750 }
1751 /* give a chance to the GPU ... */
1752 return false;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001753}
1754
Jerome Glisse225758d2010-03-09 14:45:10 +00001755bool r100_gpu_is_lockup(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001756{
Jerome Glisse225758d2010-03-09 14:45:10 +00001757 u32 rbbm_status;
1758 int r;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001759
Jerome Glisse225758d2010-03-09 14:45:10 +00001760 rbbm_status = RREG32(R_000E40_RBBM_STATUS);
1761 if (!G_000E40_GUI_ACTIVE(rbbm_status)) {
1762 r100_gpu_lockup_update(&rdev->config.r100.lockup, &rdev->cp);
1763 return false;
1764 }
1765 /* force CP activities */
1766 r = radeon_ring_lock(rdev, 2);
1767 if (!r) {
1768 /* PACKET2 NOP */
1769 radeon_ring_write(rdev, 0x80000000);
1770 radeon_ring_write(rdev, 0x80000000);
1771 radeon_ring_unlock_commit(rdev);
1772 }
1773 rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
1774 return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp);
1775}
1776
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001777void r100_bm_disable(struct radeon_device *rdev)
1778{
1779 u32 tmp;
1780
1781 /* disable bus mastering */
1782 tmp = RREG32(R_000030_BUS_CNTL);
1783 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001784 mdelay(1);
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001785 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042);
1786 mdelay(1);
1787 WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
1788 tmp = RREG32(RADEON_BUS_CNTL);
1789 mdelay(1);
1790 pci_read_config_word(rdev->pdev, 0x4, (u16*)&tmp);
1791 pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
1792 mdelay(1);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001793}
1794
Jerome Glissea2d07b72010-03-09 14:45:11 +00001795int r100_asic_reset(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001796{
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001797 struct r100_mc_save save;
1798 u32 status, tmp;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001799
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001800 r100_mc_stop(rdev, &save);
1801 status = RREG32(R_000E40_RBBM_STATUS);
1802 if (!G_000E40_GUI_ACTIVE(status)) {
1803 return 0;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001804 }
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001805 status = RREG32(R_000E40_RBBM_STATUS);
1806 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
1807 /* stop CP */
1808 WREG32(RADEON_CP_CSQ_CNTL, 0);
1809 tmp = RREG32(RADEON_CP_RB_CNTL);
1810 WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA);
1811 WREG32(RADEON_CP_RB_RPTR_WR, 0);
1812 WREG32(RADEON_CP_RB_WPTR, 0);
1813 WREG32(RADEON_CP_RB_CNTL, tmp);
1814 /* save PCI state */
1815 pci_save_state(rdev->pdev);
1816 /* disable bus mastering */
1817 r100_bm_disable(rdev);
1818 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) |
1819 S_0000F0_SOFT_RESET_RE(1) |
1820 S_0000F0_SOFT_RESET_PP(1) |
1821 S_0000F0_SOFT_RESET_RB(1));
1822 RREG32(R_0000F0_RBBM_SOFT_RESET);
1823 mdelay(500);
1824 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
1825 mdelay(1);
1826 status = RREG32(R_000E40_RBBM_STATUS);
1827 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001828 /* reset CP */
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001829 WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1));
1830 RREG32(R_0000F0_RBBM_SOFT_RESET);
1831 mdelay(500);
1832 WREG32(R_0000F0_RBBM_SOFT_RESET, 0);
1833 mdelay(1);
1834 status = RREG32(R_000E40_RBBM_STATUS);
1835 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
1836 /* restore PCI & busmastering */
1837 pci_restore_state(rdev->pdev);
1838 r100_enable_bm(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001839 /* Check if GPU is idle */
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001840 if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) ||
1841 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
1842 dev_err(rdev->dev, "failed to reset GPU\n");
1843 rdev->gpu_lockup = true;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001844 return -1;
1845 }
Jerome Glisse90aca4d2010-03-09 14:45:12 +00001846 r100_mc_resume(rdev, &save);
1847 dev_info(rdev->dev, "GPU reset succeed\n");
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001848 return 0;
1849}
1850
Alex Deucher92cde002009-12-04 10:55:12 -05001851void r100_set_common_regs(struct radeon_device *rdev)
1852{
Alex Deucher2739d492010-02-05 03:34:16 -05001853 struct drm_device *dev = rdev->ddev;
1854 bool force_dac2 = false;
Dave Airlied6680462010-03-31 13:41:35 +10001855 u32 tmp;
Alex Deucher2739d492010-02-05 03:34:16 -05001856
Alex Deucher92cde002009-12-04 10:55:12 -05001857 /* set these so they don't interfere with anything */
1858 WREG32(RADEON_OV0_SCALE_CNTL, 0);
1859 WREG32(RADEON_SUBPIC_CNTL, 0);
1860 WREG32(RADEON_VIPH_CONTROL, 0);
1861 WREG32(RADEON_I2C_CNTL_1, 0);
1862 WREG32(RADEON_DVI_I2C_CNTL_1, 0);
1863 WREG32(RADEON_CAP0_TRIG_CNTL, 0);
1864 WREG32(RADEON_CAP1_TRIG_CNTL, 0);
Alex Deucher2739d492010-02-05 03:34:16 -05001865
1866 /* always set up dac2 on rn50 and some rv100 as lots
1867 * of servers seem to wire it up to a VGA port but
1868 * don't report it in the bios connector
1869 * table.
1870 */
1871 switch (dev->pdev->device) {
1872 /* RN50 */
1873 case 0x515e:
1874 case 0x5969:
1875 force_dac2 = true;
1876 break;
1877 /* RV100*/
1878 case 0x5159:
1879 case 0x515a:
1880 /* DELL triple head servers */
1881 if ((dev->pdev->subsystem_vendor == 0x1028 /* DELL */) &&
1882 ((dev->pdev->subsystem_device == 0x016c) ||
1883 (dev->pdev->subsystem_device == 0x016d) ||
1884 (dev->pdev->subsystem_device == 0x016e) ||
1885 (dev->pdev->subsystem_device == 0x016f) ||
1886 (dev->pdev->subsystem_device == 0x0170) ||
1887 (dev->pdev->subsystem_device == 0x017d) ||
1888 (dev->pdev->subsystem_device == 0x017e) ||
1889 (dev->pdev->subsystem_device == 0x0183) ||
1890 (dev->pdev->subsystem_device == 0x018a) ||
1891 (dev->pdev->subsystem_device == 0x019a)))
1892 force_dac2 = true;
1893 break;
1894 }
1895
1896 if (force_dac2) {
1897 u32 disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
1898 u32 tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
1899 u32 dac2_cntl = RREG32(RADEON_DAC_CNTL2);
1900
1901 /* For CRT on DAC2, don't turn it on if BIOS didn't
1902 enable it, even it's detected.
1903 */
1904
1905 /* force it to crtc0 */
1906 dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
1907 dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
1908 disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
1909
1910 /* set up the TV DAC */
1911 tv_dac_cntl &= ~(RADEON_TV_DAC_PEDESTAL |
1912 RADEON_TV_DAC_STD_MASK |
1913 RADEON_TV_DAC_RDACPD |
1914 RADEON_TV_DAC_GDACPD |
1915 RADEON_TV_DAC_BDACPD |
1916 RADEON_TV_DAC_BGADJ_MASK |
1917 RADEON_TV_DAC_DACADJ_MASK);
1918 tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
1919 RADEON_TV_DAC_NHOLD |
1920 RADEON_TV_DAC_STD_PS2 |
1921 (0x58 << 16));
1922
1923 WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
1924 WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
1925 WREG32(RADEON_DAC_CNTL2, dac2_cntl);
1926 }
Dave Airlied6680462010-03-31 13:41:35 +10001927
1928 /* switch PM block to ACPI mode */
1929 tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
1930 tmp &= ~RADEON_PM_MODE_SEL;
1931 WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
1932
Alex Deucher92cde002009-12-04 10:55:12 -05001933}
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001934
1935/*
1936 * VRAM info
1937 */
1938static void r100_vram_get_type(struct radeon_device *rdev)
1939{
1940 uint32_t tmp;
1941
1942 rdev->mc.vram_is_ddr = false;
1943 if (rdev->flags & RADEON_IS_IGP)
1944 rdev->mc.vram_is_ddr = true;
1945 else if (RREG32(RADEON_MEM_SDRAM_MODE_REG) & RADEON_MEM_CFG_TYPE_DDR)
1946 rdev->mc.vram_is_ddr = true;
1947 if ((rdev->family == CHIP_RV100) ||
1948 (rdev->family == CHIP_RS100) ||
1949 (rdev->family == CHIP_RS200)) {
1950 tmp = RREG32(RADEON_MEM_CNTL);
1951 if (tmp & RV100_HALF_MODE) {
1952 rdev->mc.vram_width = 32;
1953 } else {
1954 rdev->mc.vram_width = 64;
1955 }
1956 if (rdev->flags & RADEON_SINGLE_CRTC) {
1957 rdev->mc.vram_width /= 4;
1958 rdev->mc.vram_is_ddr = true;
1959 }
1960 } else if (rdev->family <= CHIP_RV280) {
1961 tmp = RREG32(RADEON_MEM_CNTL);
1962 if (tmp & RADEON_MEM_NUM_CHANNELS_MASK) {
1963 rdev->mc.vram_width = 128;
1964 } else {
1965 rdev->mc.vram_width = 64;
1966 }
1967 } else {
1968 /* newer IGPs */
1969 rdev->mc.vram_width = 128;
1970 }
1971}
1972
Dave Airlie2a0f8912009-07-11 04:44:47 +10001973static u32 r100_get_accessible_vram(struct radeon_device *rdev)
Jerome Glisse771fe6b2009-06-05 14:42:42 +02001974{
Dave Airlie2a0f8912009-07-11 04:44:47 +10001975 u32 aper_size;
1976 u8 byte;
1977
1978 aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
1979
1980 /* Set HDP_APER_CNTL only on cards that are known not to be broken,
1981 * that is has the 2nd generation multifunction PCI interface
1982 */
1983 if (rdev->family == CHIP_RV280 ||
1984 rdev->family >= CHIP_RV350) {
1985 WREG32_P(RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL,
1986 ~RADEON_HDP_APER_CNTL);
1987 DRM_INFO("Generation 2 PCI interface, using max accessible memory\n");
1988 return aper_size * 2;
1989 }
1990
1991 /* Older cards have all sorts of funny issues to deal with. First
1992 * check if it's a multifunction card by reading the PCI config
1993 * header type... Limit those to one aperture size
1994 */
1995 pci_read_config_byte(rdev->pdev, 0xe, &byte);
1996 if (byte & 0x80) {
1997 DRM_INFO("Generation 1 PCI interface in multifunction mode\n");
1998 DRM_INFO("Limiting VRAM to one aperture\n");
1999 return aper_size;
2000 }
2001
2002 /* Single function older card. We read HDP_APER_CNTL to see how the BIOS
2003 * have set it up. We don't write this as it's broken on some ASICs but
2004 * we expect the BIOS to have done the right thing (might be too optimistic...)
2005 */
2006 if (RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL)
2007 return aper_size * 2;
2008 return aper_size;
2009}
2010
2011void r100_vram_init_sizes(struct radeon_device *rdev)
2012{
2013 u64 config_aper_size;
Dave Airlie2a0f8912009-07-11 04:44:47 +10002014
Jerome Glissed594e462010-02-17 21:54:29 +00002015 /* work out accessible VRAM */
Jerome Glissed594e462010-02-17 21:54:29 +00002016 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
2017 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
Jerome Glisse51e5fcd2010-02-19 14:33:54 +00002018 rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev);
2019 /* FIXME we don't use the second aperture yet when we could use it */
2020 if (rdev->mc.visible_vram_size > rdev->mc.aper_size)
2021 rdev->mc.visible_vram_size = rdev->mc.aper_size;
Dave Airlie2a0f8912009-07-11 04:44:47 +10002022 config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002023 if (rdev->flags & RADEON_IS_IGP) {
2024 uint32_t tom;
2025 /* read NB_TOM to get the amount of ram stolen for the GPU */
2026 tom = RREG32(RADEON_NB_TOM);
Dave Airlie7a50f012009-07-21 20:39:30 +10002027 rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16);
Dave Airlie7a50f012009-07-21 20:39:30 +10002028 WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
2029 rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002030 } else {
Dave Airlie7a50f012009-07-21 20:39:30 +10002031 rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002032 /* Some production boards of m6 will report 0
2033 * if it's 8 MB
2034 */
Dave Airlie7a50f012009-07-21 20:39:30 +10002035 if (rdev->mc.real_vram_size == 0) {
2036 rdev->mc.real_vram_size = 8192 * 1024;
2037 WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002038 }
Jerome Glissed594e462010-02-17 21:54:29 +00002039 /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM -
2040 * Novell bug 204882 + along with lots of ubuntu ones
2041 */
Dave Airlie7a50f012009-07-21 20:39:30 +10002042 if (config_aper_size > rdev->mc.real_vram_size)
2043 rdev->mc.mc_vram_size = config_aper_size;
2044 else
2045 rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002046 }
Dave Airlie2a0f8912009-07-11 04:44:47 +10002047}
2048
Dave Airlie28d52042009-09-21 14:33:58 +10002049void r100_vga_set_state(struct radeon_device *rdev, bool state)
2050{
2051 uint32_t temp;
2052
2053 temp = RREG32(RADEON_CONFIG_CNTL);
2054 if (state == false) {
2055 temp &= ~(1<<8);
2056 temp |= (1<<9);
2057 } else {
2058 temp &= ~(1<<9);
2059 }
2060 WREG32(RADEON_CONFIG_CNTL, temp);
2061}
2062
Jerome Glissed594e462010-02-17 21:54:29 +00002063void r100_mc_init(struct radeon_device *rdev)
Dave Airlie2a0f8912009-07-11 04:44:47 +10002064{
Jerome Glissed594e462010-02-17 21:54:29 +00002065 u64 base;
Dave Airlie2a0f8912009-07-11 04:44:47 +10002066
Jerome Glissed594e462010-02-17 21:54:29 +00002067 r100_vram_get_type(rdev);
Dave Airlie2a0f8912009-07-11 04:44:47 +10002068 r100_vram_init_sizes(rdev);
Jerome Glissed594e462010-02-17 21:54:29 +00002069 base = rdev->mc.aper_base;
2070 if (rdev->flags & RADEON_IS_IGP)
2071 base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16;
2072 radeon_vram_location(rdev, &rdev->mc, base);
2073 if (!(rdev->flags & RADEON_IS_AGP))
2074 radeon_gtt_location(rdev, &rdev->mc);
Alex Deucherf47299c2010-03-16 20:54:38 -04002075 radeon_update_bandwidth_info(rdev);
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002076}
2077
2078
2079/*
2080 * Indirect registers accessor
2081 */
2082void r100_pll_errata_after_index(struct radeon_device *rdev)
2083{
2084 if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) {
2085 return;
2086 }
2087 (void)RREG32(RADEON_CLOCK_CNTL_DATA);
2088 (void)RREG32(RADEON_CRTC_GEN_CNTL);
2089}
2090
2091static void r100_pll_errata_after_data(struct radeon_device *rdev)
2092{
2093 /* This workarounds is necessary on RV100, RS100 and RS200 chips
2094 * or the chip could hang on a subsequent access
2095 */
2096 if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) {
2097 udelay(5000);
2098 }
2099
2100 /* This function is required to workaround a hardware bug in some (all?)
2101 * revisions of the R300. This workaround should be called after every
2102 * CLOCK_CNTL_INDEX register access. If not, register reads afterward
2103 * may not be correct.
2104 */
2105 if (rdev->pll_errata & CHIP_ERRATA_R300_CG) {
2106 uint32_t save, tmp;
2107
2108 save = RREG32(RADEON_CLOCK_CNTL_INDEX);
2109 tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
2110 WREG32(RADEON_CLOCK_CNTL_INDEX, tmp);
2111 tmp = RREG32(RADEON_CLOCK_CNTL_DATA);
2112 WREG32(RADEON_CLOCK_CNTL_INDEX, save);
2113 }
2114}
2115
2116uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg)
2117{
2118 uint32_t data;
2119
2120 WREG8(RADEON_CLOCK_CNTL_INDEX, reg & 0x3f);
2121 r100_pll_errata_after_index(rdev);
2122 data = RREG32(RADEON_CLOCK_CNTL_DATA);
2123 r100_pll_errata_after_data(rdev);
2124 return data;
2125}
2126
2127void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
2128{
2129 WREG8(RADEON_CLOCK_CNTL_INDEX, ((reg & 0x3f) | RADEON_PLL_WR_EN));
2130 r100_pll_errata_after_index(rdev);
2131 WREG32(RADEON_CLOCK_CNTL_DATA, v);
2132 r100_pll_errata_after_data(rdev);
2133}
2134
Jerome Glissed4550902009-10-01 10:12:06 +02002135void r100_set_safe_registers(struct radeon_device *rdev)
Jerome Glisse068a1172009-06-17 13:28:30 +02002136{
Dave Airlie551ebd82009-09-01 15:25:57 +10002137 if (ASIC_IS_RN50(rdev)) {
2138 rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm;
2139 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm);
2140 } else if (rdev->family < CHIP_R200) {
2141 rdev->config.r100.reg_safe_bm = r100_reg_safe_bm;
2142 rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm);
2143 } else {
Jerome Glissed4550902009-10-01 10:12:06 +02002144 r200_set_safe_registers(rdev);
Dave Airlie551ebd82009-09-01 15:25:57 +10002145 }
Jerome Glisse068a1172009-06-17 13:28:30 +02002146}
2147
Jerome Glisse771fe6b2009-06-05 14:42:42 +02002148/*
2149 * Debugfs info
2150 */
2151#if defined(CONFIG_DEBUG_FS)
2152static int r100_debugfs_rbbm_info(struct seq_file *m, void *data)
2153{
2154 struct drm_info_node *node = (struct drm_info_node *) m->private;
2155 struct drm_device *dev = node->minor->dev;
2156 struct radeon_device *rdev = dev->dev_private;
2157 uint32_t reg, value;
2158 unsigned i;
2159
2160 seq_printf(m, "RBBM_STATUS 0x%08x\n", RREG32(RADEON_RBBM_STATUS));
2161 seq_printf(m, "RBBM_CMDFIFO_STAT 0x%08x\n", RREG32(0xE7C));
2162 seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
2163 for (i = 0; i < 64; i++) {
2164 WREG32(RADEON_RBBM_CMDFIFO_ADDR, i | 0x100);
2165 reg = (RREG32(RADEON_RBBM_CMDFIFO_DATA) - 1) >> 2;
2166 WREG32(RADEON_RBBM_CMDFIFO_ADDR, i);
2167 value = RREG32(RADEON_RBBM_CMDFIFO_DATA);
2168 seq_printf(m, "[0x%03X] 0x%04X=0x%08X\n", i, reg, value);
2169 }
2170 return 0;
2171}
2172
2173static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data)
2174{
2175 struct drm_info_node *node = (struct drm_info_node *) m->private;
2176 struct drm_device *dev = node->minor->dev;
2177 struct radeon_device *rdev = dev->dev_private;
2178 uint32_t rdp, wdp;
2179 unsigned count, i, j;
2180
2181 radeon_ring_free_size(rdev);
2182 rdp = RREG32(RADEON_CP_RB_RPTR);
2183 wdp = RREG32(RADEON_CP_RB_WPTR);
2184 count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask;
2185 seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
2186 seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp);
2187 seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp);
2188 seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw);
2189 seq_printf(m, "%u dwords in ring\n", count);
2190 for (j = 0; j <= count; j++) {
2191 i = (rdp + j) & rdev->cp.ptr_mask;
2192 seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]);
2193 }
2194 return 0;
2195}
2196
2197
2198static int r100_debugfs_cp_csq_fifo(struct seq_file *m, void *data)
2199{
2200 struct drm_info_node *node = (struct drm_info_node *) m->private;
2201 struct drm_device *dev = node->minor->dev;
2202 struct radeon_device *rdev = dev->dev_private;
2203 uint32_t csq_stat, csq2_stat, tmp;
2204 unsigned r_rptr, r_wptr, ib1_rptr, ib1_wptr, ib2_rptr, ib2_wptr;
2205 unsigned i;
2206
2207 seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT));
2208 seq_printf(m, "CP_CSQ_MODE 0x%08x\n", RREG32(RADEON_CP_CSQ_MODE));
2209 csq_stat = RREG32(RADEON_CP_CSQ_STAT);
2210 csq2_stat = RREG32(RADEON_CP_CSQ2_STAT);
2211 r_rptr = (csq_stat >> 0) & 0x3ff;
2212 r_wptr = (csq_stat >> 10) & 0x3ff;
2213 ib1_rptr = (csq_stat >> 20) & 0x3ff;
2214 ib1_wptr = (csq2_stat >> 0) & 0x3ff;
2215 ib2_rptr = (csq2_stat >> 10) & 0x3ff;
2216 ib2_wptr = (csq2_stat >> 20) & 0x3ff;
2217 seq_printf(m, "CP_CSQ_STAT 0x%08x\n", csq_stat);
2218 seq_printf(m, "CP_CSQ2_STAT 0x%08x\n", csq2_stat);
2219 seq_printf(m, "Ring rptr %u\n", r_rptr);
2220 seq_printf(m, "Ring wptr %u\n", r_wptr);
2221 seq_printf(m, "Indirect1 rptr %u\n", ib1_rptr);
2222 seq_printf(m, "Indirect1 wptr %u\n", ib1_wptr);
2223 seq_printf(m, "Indirect2 rptr %u\n", ib2_rptr);
2224 seq_printf(m, "Indirect2 wptr %u\n", ib2_wptr);
2225 /* FIXME: 0, 128, 640 depends on fifo setup see cp_init_kms
2226 * 128 = indirect1_start * 8 & 640 = indirect2_start * 8 */
2227 seq_printf(m, "Ring fifo:\n");
2228 for (i = 0; i < 256; i++) {
2229 WREG32(RADEON_CP_CSQ_ADDR, i << 2);
2230 tmp = RREG32(RADEON_CP_CSQ_DATA);
2231 seq_printf(m, "rfifo[%04d]=0x%08X\n", i, tmp);
2232 }
2233 seq_printf(m, "Indirect1 fifo:\n");
2234 for (i = 256; i <= 512; i++) {
2235 WREG32(RADEON_CP_CSQ_ADDR, i << 2);
2236 tmp = RREG32(RADEON_CP_CSQ_DATA);
2237 seq_printf(m, "ib1fifo[%04d]=0x%08X\n", i, tmp);
2238 }
2239 seq_printf(m, "Indirect2 fifo:\n");
2240 for (i = 640; i < ib1_wptr; i++) {
2241 WREG32(RADEON_CP_CSQ_ADDR, i << 2);
2242 tmp = RREG32(RADEON_CP_CSQ_DATA);
2243 seq_printf(m, "ib2fifo[%04d]=0x%08X\n", i, tmp);
2244 }
2245 return 0;
2246}
2247
2248static int r100_debugfs_mc_info(struct seq_file *m, void *data)
2249{
2250 struct drm_info_node *node = (struct drm_info_node *) m->private;
2251 struct drm_device *dev = node->minor->dev;
2252 struct radeon_device *rdev = dev->dev_private;
2253 uint32_t tmp;
2254
2255 tmp = RREG32(RADEON_CONFIG_MEMSIZE);
2256 seq_printf(m, "CONFIG_MEMSIZE 0x%08x\n", tmp);
2257 tmp = RREG32(RADEON_MC_FB_LOCATION);
2258 seq_printf(m, "MC_FB_LOCATION 0x%08x\n", tmp);
2259 tmp = RREG32(RADEON_BUS_CNTL);
2260 seq_printf(m, "BUS_CNTL 0x%08x\n", tmp);
2261 tmp = RREG32(RADEON_MC_AGP_LOCATION);
2262 seq_printf(m, "MC_AGP_LOCATION 0x%08x\n", tmp);
2263 tmp = RREG32(RADEON_AGP_BASE);
2264 seq_printf(m, "AGP_BASE 0x%08x\n", tmp);
2265 tmp = RREG32(RADEON_HOST_PATH_CNTL);
2266 seq_printf(m, "HOST_PATH_CNTL 0x%08x\n", tmp);
2267 tmp = RREG32(0x01D0);
2268 seq_printf(m, "AIC_CTRL 0x%08x\n", tmp);
2269 tmp = RREG32(RADEON_AIC_LO_ADDR);
2270 seq_printf(m, "AIC_LO_ADDR 0x%08x\n", tmp);
2271 tmp = RREG32(RADEON_AIC_HI_ADDR);
2272 seq_printf(m, "AIC_HI_ADDR 0x%08x\n", tmp);
2273 tmp = RREG32(0x01E4);
2274 seq_printf(m, "AIC_TLB_ADDR 0x%08x\n", tmp);
2275 return 0;
2276}
2277
2278static struct drm_info_list r100_debugfs_rbbm_list[] = {
2279 {"r100_rbbm_info", r100_debugfs_rbbm_info, 0, NULL},
2280};
2281
2282static struct drm_info_list r100_debugfs_cp_list[] = {
2283 {"r100_cp_ring_info", r100_debugfs_cp_ring_info, 0, NULL},
2284 {"r100_cp_csq_fifo", r100_debugfs_cp_csq_fifo, 0, NULL},
2285};
2286
2287static struct drm_info_list r100_debugfs_mc_info_list[] = {
2288 {"r100_mc_info", r100_debugfs_mc_info, 0, NULL},
2289};
2290#endif
2291
2292int r100_debugfs_rbbm_init(struct radeon_device *rdev)
2293{
2294#if defined(CONFIG_DEBUG_FS)
2295 return radeon_debugfs_add_files(rdev, r100_debugfs_rbbm_list, 1);
2296#else
2297 return 0;
2298#endif
2299}
2300
2301int r100_debugfs_cp_init(struct radeon_device *rdev)
2302{
2303#if defined(CONFIG_DEBUG_FS)
2304 return radeon_debugfs_add_files(rdev, r100_debugfs_cp_list, 2);
2305#else
2306 return 0;
2307#endif
2308}
2309
2310int r100_debugfs_mc_info_init(struct radeon_device *rdev)
2311{
2312#if defined(CONFIG_DEBUG_FS)
2313 return radeon_debugfs_add_files(rdev, r100_debugfs_mc_info_list, 1);
2314#else
2315 return 0;
2316#endif
2317}
Dave Airliee024e112009-06-24 09:48:08 +10002318
2319int r100_set_surface_reg(struct radeon_device *rdev, int reg,
2320 uint32_t tiling_flags, uint32_t pitch,
2321 uint32_t offset, uint32_t obj_size)
2322{
2323 int surf_index = reg * 16;
2324 int flags = 0;
2325
2326 /* r100/r200 divide by 16 */
2327 if (rdev->family < CHIP_R300)
2328 flags = pitch / 16;
2329 else
2330 flags = pitch / 8;
2331
2332 if (rdev->family <= CHIP_RS200) {
2333 if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
2334 == (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
2335 flags |= RADEON_SURF_TILE_COLOR_BOTH;
2336 if (tiling_flags & RADEON_TILING_MACRO)
2337 flags |= RADEON_SURF_TILE_COLOR_MACRO;
2338 } else if (rdev->family <= CHIP_RV280) {
2339 if (tiling_flags & (RADEON_TILING_MACRO))
2340 flags |= R200_SURF_TILE_COLOR_MACRO;
2341 if (tiling_flags & RADEON_TILING_MICRO)
2342 flags |= R200_SURF_TILE_COLOR_MICRO;
2343 } else {
2344 if (tiling_flags & RADEON_TILING_MACRO)
2345 flags |= R300_SURF_TILE_MACRO;
2346 if (tiling_flags & RADEON_TILING_MICRO)
2347 flags |= R300_SURF_TILE_MICRO;
2348 }
2349
Michel Dänzerc88f9f02009-09-15 17:09:30 +02002350 if (tiling_flags & RADEON_TILING_SWAP_16BIT)
2351 flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP;
2352 if (tiling_flags & RADEON_TILING_SWAP_32BIT)
2353 flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP;
2354
Dave Airliee024e112009-06-24 09:48:08 +10002355 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
2356 WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
2357 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
2358 WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1);
2359 return 0;
2360}
2361
2362void r100_clear_surface_reg(struct radeon_device *rdev, int reg)
2363{
2364 int surf_index = reg * 16;
2365 WREG32(RADEON_SURFACE0_INFO + surf_index, 0);
2366}
Jerome Glissec93bb852009-07-13 21:04:08 +02002367
2368void r100_bandwidth_update(struct radeon_device *rdev)
2369{
2370 fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff;
2371 fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff;
2372 fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff;
2373 uint32_t temp, data, mem_trcd, mem_trp, mem_tras;
2374 fixed20_12 memtcas_ff[8] = {
2375 fixed_init(1),
2376 fixed_init(2),
2377 fixed_init(3),
2378 fixed_init(0),
2379 fixed_init_half(1),
2380 fixed_init_half(2),
2381 fixed_init(0),
2382 };
2383 fixed20_12 memtcas_rs480_ff[8] = {
2384 fixed_init(0),
2385 fixed_init(1),
2386 fixed_init(2),
2387 fixed_init(3),
2388 fixed_init(0),
2389 fixed_init_half(1),
2390 fixed_init_half(2),
2391 fixed_init_half(3),
2392 };
2393 fixed20_12 memtcas2_ff[8] = {
2394 fixed_init(0),
2395 fixed_init(1),
2396 fixed_init(2),
2397 fixed_init(3),
2398 fixed_init(4),
2399 fixed_init(5),
2400 fixed_init(6),
2401 fixed_init(7),
2402 };
2403 fixed20_12 memtrbs[8] = {
2404 fixed_init(1),
2405 fixed_init_half(1),
2406 fixed_init(2),
2407 fixed_init_half(2),
2408 fixed_init(3),
2409 fixed_init_half(3),
2410 fixed_init(4),
2411 fixed_init_half(4)
2412 };
2413 fixed20_12 memtrbs_r4xx[8] = {
2414 fixed_init(4),
2415 fixed_init(5),
2416 fixed_init(6),
2417 fixed_init(7),
2418 fixed_init(8),
2419 fixed_init(9),
2420 fixed_init(10),
2421 fixed_init(11)
2422 };
2423 fixed20_12 min_mem_eff;
2424 fixed20_12 mc_latency_sclk, mc_latency_mclk, k1;
2425 fixed20_12 cur_latency_mclk, cur_latency_sclk;
2426 fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate,
2427 disp_drain_rate2, read_return_rate;
2428 fixed20_12 time_disp1_drop_priority;
2429 int c;
2430 int cur_size = 16; /* in octawords */
2431 int critical_point = 0, critical_point2;
2432/* uint32_t read_return_rate, time_disp1_drop_priority; */
2433 int stop_req, max_stop_req;
2434 struct drm_display_mode *mode1 = NULL;
2435 struct drm_display_mode *mode2 = NULL;
2436 uint32_t pixel_bytes1 = 0;
2437 uint32_t pixel_bytes2 = 0;
2438
Alex Deucherf46c0122010-03-31 00:33:27 -04002439 radeon_update_display_priority(rdev);
2440
Jerome Glissec93bb852009-07-13 21:04:08 +02002441 if (rdev->mode_info.crtcs[0]->base.enabled) {
2442 mode1 = &rdev->mode_info.crtcs[0]->base.mode;
2443 pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
2444 }
Dave Airliedfee5612009-10-02 09:19:09 +10002445 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
2446 if (rdev->mode_info.crtcs[1]->base.enabled) {
2447 mode2 = &rdev->mode_info.crtcs[1]->base.mode;
2448 pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8;
2449 }
Jerome Glissec93bb852009-07-13 21:04:08 +02002450 }
2451
2452 min_mem_eff.full = rfixed_const_8(0);
2453 /* get modes */
2454 if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) {
2455 uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER);
2456 mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT);
2457 mc_init_misc_lat_timer &= ~(R300_MC_DISP0R_INIT_LAT_MASK << R300_MC_DISP0R_INIT_LAT_SHIFT);
2458 /* check crtc enables */
2459 if (mode2)
2460 mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT);
2461 if (mode1)
2462 mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT);
2463 WREG32(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
2464 }
2465
2466 /*
2467 * determine is there is enough bw for current mode
2468 */
Alex Deucherf47299c2010-03-16 20:54:38 -04002469 sclk_ff = rdev->pm.sclk;
2470 mclk_ff = rdev->pm.mclk;
Jerome Glissec93bb852009-07-13 21:04:08 +02002471
2472 temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
2473 temp_ff.full = rfixed_const(temp);
2474 mem_bw.full = rfixed_mul(mclk_ff, temp_ff);
2475
2476 pix_clk.full = 0;
2477 pix_clk2.full = 0;
2478 peak_disp_bw.full = 0;
2479 if (mode1) {
2480 temp_ff.full = rfixed_const(1000);
2481 pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */
2482 pix_clk.full = rfixed_div(pix_clk, temp_ff);
2483 temp_ff.full = rfixed_const(pixel_bytes1);
2484 peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff);
2485 }
2486 if (mode2) {
2487 temp_ff.full = rfixed_const(1000);
2488 pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */
2489 pix_clk2.full = rfixed_div(pix_clk2, temp_ff);
2490 temp_ff.full = rfixed_const(pixel_bytes2);
2491 peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff);
2492 }
2493
2494 mem_bw.full = rfixed_mul(mem_bw, min_mem_eff);
2495 if (peak_disp_bw.full >= mem_bw.full) {
2496 DRM_ERROR("You may not have enough display bandwidth for current mode\n"
2497 "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
2498 }
2499
2500 /* Get values from the EXT_MEM_CNTL register...converting its contents. */
2501 temp = RREG32(RADEON_MEM_TIMING_CNTL);
2502 if ((rdev->family == CHIP_RV100) || (rdev->flags & RADEON_IS_IGP)) { /* RV100, M6, IGPs */
2503 mem_trcd = ((temp >> 2) & 0x3) + 1;
2504 mem_trp = ((temp & 0x3)) + 1;
2505 mem_tras = ((temp & 0x70) >> 4) + 1;
2506 } else if (rdev->family == CHIP_R300 ||
2507 rdev->family == CHIP_R350) { /* r300, r350 */
2508 mem_trcd = (temp & 0x7) + 1;
2509 mem_trp = ((temp >> 8) & 0x7) + 1;
2510 mem_tras = ((temp >> 11) & 0xf) + 4;
2511 } else if (rdev->family == CHIP_RV350 ||
2512 rdev->family <= CHIP_RV380) {
2513 /* rv3x0 */
2514 mem_trcd = (temp & 0x7) + 3;
2515 mem_trp = ((temp >> 8) & 0x7) + 3;
2516 mem_tras = ((temp >> 11) & 0xf) + 6;
2517 } else if (rdev->family == CHIP_R420 ||
2518 rdev->family == CHIP_R423 ||
2519 rdev->family == CHIP_RV410) {
2520 /* r4xx */
2521 mem_trcd = (temp & 0xf) + 3;
2522 if (mem_trcd > 15)
2523 mem_trcd = 15;
2524 mem_trp = ((temp >> 8) & 0xf) + 3;
2525 if (mem_trp > 15)
2526 mem_trp = 15;
2527 mem_tras = ((temp >> 12) & 0x1f) + 6;
2528 if (mem_tras > 31)
2529 mem_tras = 31;
2530 } else { /* RV200, R200 */
2531 mem_trcd = (temp & 0x7) + 1;
2532 mem_trp = ((temp >> 8) & 0x7) + 1;
2533 mem_tras = ((temp >> 12) & 0xf) + 4;
2534 }
2535 /* convert to FF */
2536 trcd_ff.full = rfixed_const(mem_trcd);
2537 trp_ff.full = rfixed_const(mem_trp);
2538 tras_ff.full = rfixed_const(mem_tras);
2539
2540 /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
2541 temp = RREG32(RADEON_MEM_SDRAM_MODE_REG);
2542 data = (temp & (7 << 20)) >> 20;
2543 if ((rdev->family == CHIP_RV100) || rdev->flags & RADEON_IS_IGP) {
2544 if (rdev->family == CHIP_RS480) /* don't think rs400 */
2545 tcas_ff = memtcas_rs480_ff[data];
2546 else
2547 tcas_ff = memtcas_ff[data];
2548 } else
2549 tcas_ff = memtcas2_ff[data];
2550
2551 if (rdev->family == CHIP_RS400 ||
2552 rdev->family == CHIP_RS480) {
2553 /* extra cas latency stored in bits 23-25 0-4 clocks */
2554 data = (temp >> 23) & 0x7;
2555 if (data < 5)
2556 tcas_ff.full += rfixed_const(data);
2557 }
2558
2559 if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) {
2560 /* on the R300, Tcas is included in Trbs.
2561 */
2562 temp = RREG32(RADEON_MEM_CNTL);
2563 data = (R300_MEM_NUM_CHANNELS_MASK & temp);
2564 if (data == 1) {
2565 if (R300_MEM_USE_CD_CH_ONLY & temp) {
2566 temp = RREG32(R300_MC_IND_INDEX);
2567 temp &= ~R300_MC_IND_ADDR_MASK;
2568 temp |= R300_MC_READ_CNTL_CD_mcind;
2569 WREG32(R300_MC_IND_INDEX, temp);
2570 temp = RREG32(R300_MC_IND_DATA);
2571 data = (R300_MEM_RBS_POSITION_C_MASK & temp);
2572 } else {
2573 temp = RREG32(R300_MC_READ_CNTL_AB);
2574 data = (R300_MEM_RBS_POSITION_A_MASK & temp);
2575 }
2576 } else {
2577 temp = RREG32(R300_MC_READ_CNTL_AB);
2578 data = (R300_MEM_RBS_POSITION_A_MASK & temp);
2579 }
2580 if (rdev->family == CHIP_RV410 ||
2581 rdev->family == CHIP_R420 ||
2582 rdev->family == CHIP_R423)
2583 trbs_ff = memtrbs_r4xx[data];
2584 else
2585 trbs_ff = memtrbs[data];
2586 tcas_ff.full += trbs_ff.full;
2587 }
2588
2589 sclk_eff_ff.full = sclk_ff.full;
2590
2591 if (rdev->flags & RADEON_IS_AGP) {
2592 fixed20_12 agpmode_ff;
2593 agpmode_ff.full = rfixed_const(radeon_agpmode);
2594 temp_ff.full = rfixed_const_666(16);
2595 sclk_eff_ff.full -= rfixed_mul(agpmode_ff, temp_ff);
2596 }
2597 /* TODO PCIE lanes may affect this - agpmode == 16?? */
2598
2599 if (ASIC_IS_R300(rdev)) {
2600 sclk_delay_ff.full = rfixed_const(250);
2601 } else {
2602 if ((rdev->family == CHIP_RV100) ||
2603 rdev->flags & RADEON_IS_IGP) {
2604 if (rdev->mc.vram_is_ddr)
2605 sclk_delay_ff.full = rfixed_const(41);
2606 else
2607 sclk_delay_ff.full = rfixed_const(33);
2608 } else {
2609 if (rdev->mc.vram_width == 128)
2610 sclk_delay_ff.full = rfixed_const(57);
2611 else
2612 sclk_delay_ff.full = rfixed_const(41);
2613 }
2614 }
2615
2616 mc_latency_sclk.full = rfixed_div(sclk_delay_ff, sclk_eff_ff);
2617
2618 if (rdev->mc.vram_is_ddr) {
2619 if (rdev->mc.vram_width == 32) {
2620 k1.full = rfixed_const(40);
2621 c = 3;
2622 } else {
2623 k1.full = rfixed_const(20);
2624 c = 1;
2625 }
2626 } else {
2627 k1.full = rfixed_const(40);
2628 c = 3;
2629 }
2630
2631 temp_ff.full = rfixed_const(2);
2632 mc_latency_mclk.full = rfixed_mul(trcd_ff, temp_ff);
2633 temp_ff.full = rfixed_const(c);
2634 mc_latency_mclk.full += rfixed_mul(tcas_ff, temp_ff);
2635 temp_ff.full = rfixed_const(4);
2636 mc_latency_mclk.full += rfixed_mul(tras_ff, temp_ff);
2637 mc_latency_mclk.full += rfixed_mul(trp_ff, temp_ff);
2638 mc_latency_mclk.full += k1.full;
2639
2640 mc_latency_mclk.full = rfixed_div(mc_latency_mclk, mclk_ff);
2641 mc_latency_mclk.full += rfixed_div(temp_ff, sclk_eff_ff);
2642
2643 /*
2644 HW cursor time assuming worst case of full size colour cursor.
2645 */
2646 temp_ff.full = rfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1))));
2647 temp_ff.full += trcd_ff.full;
2648 if (temp_ff.full < tras_ff.full)
2649 temp_ff.full = tras_ff.full;
2650 cur_latency_mclk.full = rfixed_div(temp_ff, mclk_ff);
2651
2652 temp_ff.full = rfixed_const(cur_size);
2653 cur_latency_sclk.full = rfixed_div(temp_ff, sclk_eff_ff);
2654 /*
2655 Find the total latency for the display data.
2656 */
Michel Dänzerb5fc9012009-10-08 10:44:10 +02002657 disp_latency_overhead.full = rfixed_const(8);
Jerome Glissec93bb852009-07-13 21:04:08 +02002658 disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff);
2659 mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full;
2660 mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full;
2661
2662 if (mc_latency_mclk.full > mc_latency_sclk.full)
2663 disp_latency.full = mc_latency_mclk.full;
2664 else
2665 disp_latency.full = mc_latency_sclk.full;
2666
2667 /* setup Max GRPH_STOP_REQ default value */
2668 if (ASIC_IS_RV100(rdev))
2669 max_stop_req = 0x5c;
2670 else
2671 max_stop_req = 0x7c;
2672
2673 if (mode1) {
2674 /* CRTC1
2675 Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
2676 GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
2677 */
2678 stop_req = mode1->hdisplay * pixel_bytes1 / 16;
2679
2680 if (stop_req > max_stop_req)
2681 stop_req = max_stop_req;
2682
2683 /*
2684 Find the drain rate of the display buffer.
2685 */
2686 temp_ff.full = rfixed_const((16/pixel_bytes1));
2687 disp_drain_rate.full = rfixed_div(pix_clk, temp_ff);
2688
2689 /*
2690 Find the critical point of the display buffer.
2691 */
2692 crit_point_ff.full = rfixed_mul(disp_drain_rate, disp_latency);
2693 crit_point_ff.full += rfixed_const_half(0);
2694
2695 critical_point = rfixed_trunc(crit_point_ff);
2696
2697 if (rdev->disp_priority == 2) {
2698 critical_point = 0;
2699 }
2700
2701 /*
2702 The critical point should never be above max_stop_req-4. Setting
2703 GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
2704 */
2705 if (max_stop_req - critical_point < 4)
2706 critical_point = 0;
2707
2708 if (critical_point == 0 && mode2 && rdev->family == CHIP_R300) {
2709 /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
2710 critical_point = 0x10;
2711 }
2712
2713 temp = RREG32(RADEON_GRPH_BUFFER_CNTL);
2714 temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
2715 temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
2716 temp &= ~(RADEON_GRPH_START_REQ_MASK);
2717 if ((rdev->family == CHIP_R350) &&
2718 (stop_req > 0x15)) {
2719 stop_req -= 0x10;
2720 }
2721 temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
2722 temp |= RADEON_GRPH_BUFFER_SIZE;
2723 temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
2724 RADEON_GRPH_CRITICAL_AT_SOF |
2725 RADEON_GRPH_STOP_CNTL);
2726 /*
2727 Write the result into the register.
2728 */
2729 WREG32(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
2730 (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
2731
2732#if 0
2733 if ((rdev->family == CHIP_RS400) ||
2734 (rdev->family == CHIP_RS480)) {
2735 /* attempt to program RS400 disp regs correctly ??? */
2736 temp = RREG32(RS400_DISP1_REG_CNTL);
2737 temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK |
2738 RS400_DISP1_STOP_REQ_LEVEL_MASK);
2739 WREG32(RS400_DISP1_REQ_CNTL1, (temp |
2740 (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
2741 (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
2742 temp = RREG32(RS400_DMIF_MEM_CNTL1);
2743 temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK |
2744 RS400_DISP1_CRITICAL_POINT_STOP_MASK);
2745 WREG32(RS400_DMIF_MEM_CNTL1, (temp |
2746 (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) |
2747 (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT)));
2748 }
2749#endif
2750
2751 DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n",
2752 /* (unsigned int)info->SavedReg->grph_buffer_cntl, */
2753 (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL));
2754 }
2755
2756 if (mode2) {
2757 u32 grph2_cntl;
2758 stop_req = mode2->hdisplay * pixel_bytes2 / 16;
2759
2760 if (stop_req > max_stop_req)
2761 stop_req = max_stop_req;
2762
2763 /*
2764 Find the drain rate of the display buffer.
2765 */
2766 temp_ff.full = rfixed_const((16/pixel_bytes2));
2767 disp_drain_rate2.full = rfixed_div(pix_clk2, temp_ff);
2768
2769 grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL);
2770 grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK);
2771 grph2_cntl |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
2772 grph2_cntl &= ~(RADEON_GRPH_START_REQ_MASK);
2773 if ((rdev->family == CHIP_R350) &&
2774 (stop_req > 0x15)) {
2775 stop_req -= 0x10;
2776 }
2777 grph2_cntl |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
2778 grph2_cntl |= RADEON_GRPH_BUFFER_SIZE;
2779 grph2_cntl &= ~(RADEON_GRPH_CRITICAL_CNTL |
2780 RADEON_GRPH_CRITICAL_AT_SOF |
2781 RADEON_GRPH_STOP_CNTL);
2782
2783 if ((rdev->family == CHIP_RS100) ||
2784 (rdev->family == CHIP_RS200))
2785 critical_point2 = 0;
2786 else {
2787 temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128;
2788 temp_ff.full = rfixed_const(temp);
2789 temp_ff.full = rfixed_mul(mclk_ff, temp_ff);
2790 if (sclk_ff.full < temp_ff.full)
2791 temp_ff.full = sclk_ff.full;
2792
2793 read_return_rate.full = temp_ff.full;
2794
2795 if (mode1) {
2796 temp_ff.full = read_return_rate.full - disp_drain_rate.full;
2797 time_disp1_drop_priority.full = rfixed_div(crit_point_ff, temp_ff);
2798 } else {
2799 time_disp1_drop_priority.full = 0;
2800 }
2801 crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full;
2802 crit_point_ff.full = rfixed_mul(crit_point_ff, disp_drain_rate2);
2803 crit_point_ff.full += rfixed_const_half(0);
2804
2805 critical_point2 = rfixed_trunc(crit_point_ff);
2806
2807 if (rdev->disp_priority == 2) {
2808 critical_point2 = 0;
2809 }
2810
2811 if (max_stop_req - critical_point2 < 4)
2812 critical_point2 = 0;
2813
2814 }
2815
2816 if (critical_point2 == 0 && rdev->family == CHIP_R300) {
2817 /* some R300 cards have problem with this set to 0 */
2818 critical_point2 = 0x10;
2819 }
2820
2821 WREG32(RADEON_GRPH2_BUFFER_CNTL, ((grph2_cntl & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
2822 (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
2823
2824 if ((rdev->family == CHIP_RS400) ||
2825 (rdev->family == CHIP_RS480)) {
2826#if 0
2827 /* attempt to program RS400 disp2 regs correctly ??? */
2828 temp = RREG32(RS400_DISP2_REQ_CNTL1);
2829 temp &= ~(RS400_DISP2_START_REQ_LEVEL_MASK |
2830 RS400_DISP2_STOP_REQ_LEVEL_MASK);
2831 WREG32(RS400_DISP2_REQ_CNTL1, (temp |
2832 (critical_point2 << RS400_DISP1_START_REQ_LEVEL_SHIFT) |
2833 (critical_point2 << RS400_DISP1_STOP_REQ_LEVEL_SHIFT)));
2834 temp = RREG32(RS400_DISP2_REQ_CNTL2);
2835 temp &= ~(RS400_DISP2_CRITICAL_POINT_START_MASK |
2836 RS400_DISP2_CRITICAL_POINT_STOP_MASK);
2837 WREG32(RS400_DISP2_REQ_CNTL2, (temp |
2838 (critical_point2 << RS400_DISP2_CRITICAL_POINT_START_SHIFT) |
2839 (critical_point2 << RS400_DISP2_CRITICAL_POINT_STOP_SHIFT)));
2840#endif
2841 WREG32(RS400_DISP2_REQ_CNTL1, 0x105DC1CC);
2842 WREG32(RS400_DISP2_REQ_CNTL2, 0x2749D000);
2843 WREG32(RS400_DMIF_MEM_CNTL1, 0x29CA71DC);
2844 WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC);
2845 }
2846
2847 DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n",
2848 (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL));
2849 }
2850}
Dave Airlie551ebd82009-09-01 15:25:57 +10002851
2852static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
2853{
2854 DRM_ERROR("pitch %d\n", t->pitch);
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002855 DRM_ERROR("use_pitch %d\n", t->use_pitch);
Dave Airlie551ebd82009-09-01 15:25:57 +10002856 DRM_ERROR("width %d\n", t->width);
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002857 DRM_ERROR("width_11 %d\n", t->width_11);
Dave Airlie551ebd82009-09-01 15:25:57 +10002858 DRM_ERROR("height %d\n", t->height);
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002859 DRM_ERROR("height_11 %d\n", t->height_11);
Dave Airlie551ebd82009-09-01 15:25:57 +10002860 DRM_ERROR("num levels %d\n", t->num_levels);
2861 DRM_ERROR("depth %d\n", t->txdepth);
2862 DRM_ERROR("bpp %d\n", t->cpp);
2863 DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
2864 DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
2865 DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
Dave Airlied785d782009-12-07 13:16:06 +10002866 DRM_ERROR("compress format %d\n", t->compress_format);
Dave Airlie551ebd82009-09-01 15:25:57 +10002867}
2868
2869static int r100_cs_track_cube(struct radeon_device *rdev,
2870 struct r100_cs_track *track, unsigned idx)
2871{
2872 unsigned face, w, h;
Jerome Glisse4c788672009-11-20 14:29:23 +01002873 struct radeon_bo *cube_robj;
Dave Airlie551ebd82009-09-01 15:25:57 +10002874 unsigned long size;
2875
2876 for (face = 0; face < 5; face++) {
2877 cube_robj = track->textures[idx].cube_info[face].robj;
2878 w = track->textures[idx].cube_info[face].width;
2879 h = track->textures[idx].cube_info[face].height;
2880
2881 size = w * h;
2882 size *= track->textures[idx].cpp;
2883
2884 size += track->textures[idx].cube_info[face].offset;
2885
Jerome Glisse4c788672009-11-20 14:29:23 +01002886 if (size > radeon_bo_size(cube_robj)) {
Dave Airlie551ebd82009-09-01 15:25:57 +10002887 DRM_ERROR("Cube texture offset greater than object size %lu %lu\n",
Jerome Glisse4c788672009-11-20 14:29:23 +01002888 size, radeon_bo_size(cube_robj));
Dave Airlie551ebd82009-09-01 15:25:57 +10002889 r100_cs_track_texture_print(&track->textures[idx]);
2890 return -1;
2891 }
2892 }
2893 return 0;
2894}
2895
Dave Airlied785d782009-12-07 13:16:06 +10002896static int r100_track_compress_size(int compress_format, int w, int h)
2897{
2898 int block_width, block_height, block_bytes;
2899 int wblocks, hblocks;
2900 int min_wblocks;
2901 int sz;
2902
2903 block_width = 4;
2904 block_height = 4;
2905
2906 switch (compress_format) {
2907 case R100_TRACK_COMP_DXT1:
2908 block_bytes = 8;
2909 min_wblocks = 4;
2910 break;
2911 default:
2912 case R100_TRACK_COMP_DXT35:
2913 block_bytes = 16;
2914 min_wblocks = 2;
2915 break;
2916 }
2917
2918 hblocks = (h + block_height - 1) / block_height;
2919 wblocks = (w + block_width - 1) / block_width;
2920 if (wblocks < min_wblocks)
2921 wblocks = min_wblocks;
2922 sz = wblocks * hblocks * block_bytes;
2923 return sz;
2924}
2925
Dave Airlie551ebd82009-09-01 15:25:57 +10002926static int r100_cs_track_texture_check(struct radeon_device *rdev,
2927 struct r100_cs_track *track)
2928{
Jerome Glisse4c788672009-11-20 14:29:23 +01002929 struct radeon_bo *robj;
Dave Airlie551ebd82009-09-01 15:25:57 +10002930 unsigned long size;
Marek Olšákb73c5f82010-04-11 03:18:52 +02002931 unsigned u, i, w, h, d;
Dave Airlie551ebd82009-09-01 15:25:57 +10002932 int ret;
2933
2934 for (u = 0; u < track->num_texture; u++) {
2935 if (!track->textures[u].enabled)
2936 continue;
2937 robj = track->textures[u].robj;
2938 if (robj == NULL) {
2939 DRM_ERROR("No texture bound to unit %u\n", u);
2940 return -EINVAL;
2941 }
2942 size = 0;
2943 for (i = 0; i <= track->textures[u].num_levels; i++) {
2944 if (track->textures[u].use_pitch) {
2945 if (rdev->family < CHIP_R300)
2946 w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i);
2947 else
2948 w = track->textures[u].pitch / (1 << i);
2949 } else {
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002950 w = track->textures[u].width;
Dave Airlie551ebd82009-09-01 15:25:57 +10002951 if (rdev->family >= CHIP_RV515)
2952 w |= track->textures[u].width_11;
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002953 w = w / (1 << i);
Dave Airlie551ebd82009-09-01 15:25:57 +10002954 if (track->textures[u].roundup_w)
2955 w = roundup_pow_of_two(w);
2956 }
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002957 h = track->textures[u].height;
Dave Airlie551ebd82009-09-01 15:25:57 +10002958 if (rdev->family >= CHIP_RV515)
2959 h |= track->textures[u].height_11;
Mathias Fröhlichceb776b2009-10-19 12:50:41 -04002960 h = h / (1 << i);
Dave Airlie551ebd82009-09-01 15:25:57 +10002961 if (track->textures[u].roundup_h)
2962 h = roundup_pow_of_two(h);
Marek Olšákb73c5f82010-04-11 03:18:52 +02002963 if (track->textures[u].tex_coord_type == 1) {
2964 d = (1 << track->textures[u].txdepth) / (1 << i);
2965 if (!d)
2966 d = 1;
2967 } else {
2968 d = 1;
2969 }
Dave Airlied785d782009-12-07 13:16:06 +10002970 if (track->textures[u].compress_format) {
2971
Marek Olšákb73c5f82010-04-11 03:18:52 +02002972 size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d;
Dave Airlied785d782009-12-07 13:16:06 +10002973 /* compressed textures are block based */
2974 } else
Marek Olšákb73c5f82010-04-11 03:18:52 +02002975 size += w * h * d;
Dave Airlie551ebd82009-09-01 15:25:57 +10002976 }
2977 size *= track->textures[u].cpp;
Dave Airlied785d782009-12-07 13:16:06 +10002978
Dave Airlie551ebd82009-09-01 15:25:57 +10002979 switch (track->textures[u].tex_coord_type) {
2980 case 0:
Dave Airlie551ebd82009-09-01 15:25:57 +10002981 case 1:
Dave Airlie551ebd82009-09-01 15:25:57 +10002982 break;
2983 case 2:
2984 if (track->separate_cube) {
2985 ret = r100_cs_track_cube(rdev, track, u);
2986 if (ret)
2987 return ret;
2988 } else
2989 size *= 6;
2990 break;
2991 default:
2992 DRM_ERROR("Invalid texture coordinate type %u for unit "
2993 "%u\n", track->textures[u].tex_coord_type, u);
2994 return -EINVAL;
2995 }
Jerome Glisse4c788672009-11-20 14:29:23 +01002996 if (size > radeon_bo_size(robj)) {
Dave Airlie551ebd82009-09-01 15:25:57 +10002997 DRM_ERROR("Texture of unit %u needs %lu bytes but is "
Jerome Glisse4c788672009-11-20 14:29:23 +01002998 "%lu\n", u, size, radeon_bo_size(robj));
Dave Airlie551ebd82009-09-01 15:25:57 +10002999 r100_cs_track_texture_print(&track->textures[u]);
3000 return -EINVAL;
3001 }
3002 }
3003 return 0;
3004}
3005
3006int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
3007{
3008 unsigned i;
3009 unsigned long size;
3010 unsigned prim_walk;
3011 unsigned nverts;
3012
3013 for (i = 0; i < track->num_cb; i++) {
3014 if (track->cb[i].robj == NULL) {
Marek Olšák46c64d42009-12-17 06:02:28 +01003015 if (!(track->fastfill || track->color_channel_mask ||
3016 track->blend_read_enable)) {
3017 continue;
3018 }
Dave Airlie551ebd82009-09-01 15:25:57 +10003019 DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
3020 return -EINVAL;
3021 }
3022 size = track->cb[i].pitch * track->cb[i].cpp * track->maxy;
3023 size += track->cb[i].offset;
Jerome Glisse4c788672009-11-20 14:29:23 +01003024 if (size > radeon_bo_size(track->cb[i].robj)) {
Dave Airlie551ebd82009-09-01 15:25:57 +10003025 DRM_ERROR("[drm] Buffer too small for color buffer %d "
3026 "(need %lu have %lu) !\n", i, size,
Jerome Glisse4c788672009-11-20 14:29:23 +01003027 radeon_bo_size(track->cb[i].robj));
Dave Airlie551ebd82009-09-01 15:25:57 +10003028 DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n",
3029 i, track->cb[i].pitch, track->cb[i].cpp,
3030 track->cb[i].offset, track->maxy);
3031 return -EINVAL;
3032 }
3033 }
3034 if (track->z_enabled) {
3035 if (track->zb.robj == NULL) {
3036 DRM_ERROR("[drm] No buffer for z buffer !\n");
3037 return -EINVAL;
3038 }
3039 size = track->zb.pitch * track->zb.cpp * track->maxy;
3040 size += track->zb.offset;
Jerome Glisse4c788672009-11-20 14:29:23 +01003041 if (size > radeon_bo_size(track->zb.robj)) {
Dave Airlie551ebd82009-09-01 15:25:57 +10003042 DRM_ERROR("[drm] Buffer too small for z buffer "
3043 "(need %lu have %lu) !\n", size,
Jerome Glisse4c788672009-11-20 14:29:23 +01003044 radeon_bo_size(track->zb.robj));
Dave Airlie551ebd82009-09-01 15:25:57 +10003045 DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n",
3046 track->zb.pitch, track->zb.cpp,
3047 track->zb.offset, track->maxy);
3048 return -EINVAL;
3049 }
3050 }
3051 prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
Marek Olšákcae94b02010-02-21 21:24:15 +01003052 if (track->vap_vf_cntl & (1 << 14)) {
3053 nverts = track->vap_alt_nverts;
3054 } else {
3055 nverts = (track->vap_vf_cntl >> 16) & 0xFFFF;
3056 }
Dave Airlie551ebd82009-09-01 15:25:57 +10003057 switch (prim_walk) {
3058 case 1:
3059 for (i = 0; i < track->num_arrays; i++) {
3060 size = track->arrays[i].esize * track->max_indx * 4;
3061 if (track->arrays[i].robj == NULL) {
3062 DRM_ERROR("(PW %u) Vertex array %u no buffer "
3063 "bound\n", prim_walk, i);
3064 return -EINVAL;
3065 }
Jerome Glisse4c788672009-11-20 14:29:23 +01003066 if (size > radeon_bo_size(track->arrays[i].robj)) {
3067 dev_err(rdev->dev, "(PW %u) Vertex array %u "
3068 "need %lu dwords have %lu dwords\n",
3069 prim_walk, i, size >> 2,
3070 radeon_bo_size(track->arrays[i].robj)
3071 >> 2);
Dave Airlie551ebd82009-09-01 15:25:57 +10003072 DRM_ERROR("Max indices %u\n", track->max_indx);
3073 return -EINVAL;
3074 }
3075 }
3076 break;
3077 case 2:
3078 for (i = 0; i < track->num_arrays; i++) {
3079 size = track->arrays[i].esize * (nverts - 1) * 4;
3080 if (track->arrays[i].robj == NULL) {
3081 DRM_ERROR("(PW %u) Vertex array %u no buffer "
3082 "bound\n", prim_walk, i);
3083 return -EINVAL;
3084 }
Jerome Glisse4c788672009-11-20 14:29:23 +01003085 if (size > radeon_bo_size(track->arrays[i].robj)) {
3086 dev_err(rdev->dev, "(PW %u) Vertex array %u "
3087 "need %lu dwords have %lu dwords\n",
3088 prim_walk, i, size >> 2,
3089 radeon_bo_size(track->arrays[i].robj)
3090 >> 2);
Dave Airlie551ebd82009-09-01 15:25:57 +10003091 return -EINVAL;
3092 }
3093 }
3094 break;
3095 case 3:
3096 size = track->vtx_size * nverts;
3097 if (size != track->immd_dwords) {
3098 DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n",
3099 track->immd_dwords, size);
3100 DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n",
3101 nverts, track->vtx_size);
3102 return -EINVAL;
3103 }
3104 break;
3105 default:
3106 DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n",
3107 prim_walk);
3108 return -EINVAL;
3109 }
3110 return r100_cs_track_texture_check(rdev, track);
3111}
3112
3113void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track)
3114{
3115 unsigned i, face;
3116
3117 if (rdev->family < CHIP_R300) {
3118 track->num_cb = 1;
3119 if (rdev->family <= CHIP_RS200)
3120 track->num_texture = 3;
3121 else
3122 track->num_texture = 6;
3123 track->maxy = 2048;
3124 track->separate_cube = 1;
3125 } else {
3126 track->num_cb = 4;
3127 track->num_texture = 16;
3128 track->maxy = 4096;
3129 track->separate_cube = 0;
3130 }
3131
3132 for (i = 0; i < track->num_cb; i++) {
3133 track->cb[i].robj = NULL;
3134 track->cb[i].pitch = 8192;
3135 track->cb[i].cpp = 16;
3136 track->cb[i].offset = 0;
3137 }
3138 track->z_enabled = true;
3139 track->zb.robj = NULL;
3140 track->zb.pitch = 8192;
3141 track->zb.cpp = 4;
3142 track->zb.offset = 0;
3143 track->vtx_size = 0x7F;
3144 track->immd_dwords = 0xFFFFFFFFUL;
3145 track->num_arrays = 11;
3146 track->max_indx = 0x00FFFFFFUL;
3147 for (i = 0; i < track->num_arrays; i++) {
3148 track->arrays[i].robj = NULL;
3149 track->arrays[i].esize = 0x7F;
3150 }
3151 for (i = 0; i < track->num_texture; i++) {
Dave Airlied785d782009-12-07 13:16:06 +10003152 track->textures[i].compress_format = R100_TRACK_COMP_NONE;
Dave Airlie551ebd82009-09-01 15:25:57 +10003153 track->textures[i].pitch = 16536;
3154 track->textures[i].width = 16536;
3155 track->textures[i].height = 16536;
3156 track->textures[i].width_11 = 1 << 11;
3157 track->textures[i].height_11 = 1 << 11;
3158 track->textures[i].num_levels = 12;
3159 if (rdev->family <= CHIP_RS200) {
3160 track->textures[i].tex_coord_type = 0;
3161 track->textures[i].txdepth = 0;
3162 } else {
3163 track->textures[i].txdepth = 16;
3164 track->textures[i].tex_coord_type = 1;
3165 }
3166 track->textures[i].cpp = 64;
3167 track->textures[i].robj = NULL;
3168 /* CS IB emission code makes sure texture unit are disabled */
3169 track->textures[i].enabled = false;
3170 track->textures[i].roundup_w = true;
3171 track->textures[i].roundup_h = true;
3172 if (track->separate_cube)
3173 for (face = 0; face < 5; face++) {
3174 track->textures[i].cube_info[face].robj = NULL;
3175 track->textures[i].cube_info[face].width = 16536;
3176 track->textures[i].cube_info[face].height = 16536;
3177 track->textures[i].cube_info[face].offset = 0;
3178 }
3179 }
3180}
Jerome Glisse3ce0a232009-09-08 10:10:24 +10003181
3182int r100_ring_test(struct radeon_device *rdev)
3183{
3184 uint32_t scratch;
3185 uint32_t tmp = 0;
3186 unsigned i;
3187 int r;
3188
3189 r = radeon_scratch_get(rdev, &scratch);
3190 if (r) {
3191 DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r);
3192 return r;
3193 }
3194 WREG32(scratch, 0xCAFEDEAD);
3195 r = radeon_ring_lock(rdev, 2);
3196 if (r) {
3197 DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3198 radeon_scratch_free(rdev, scratch);
3199 return r;
3200 }
3201 radeon_ring_write(rdev, PACKET0(scratch, 0));
3202 radeon_ring_write(rdev, 0xDEADBEEF);
3203 radeon_ring_unlock_commit(rdev);
3204 for (i = 0; i < rdev->usec_timeout; i++) {
3205 tmp = RREG32(scratch);
3206 if (tmp == 0xDEADBEEF) {
3207 break;
3208 }
3209 DRM_UDELAY(1);
3210 }
3211 if (i < rdev->usec_timeout) {
3212 DRM_INFO("ring test succeeded in %d usecs\n", i);
3213 } else {
3214 DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
3215 scratch, tmp);
3216 r = -EINVAL;
3217 }
3218 radeon_scratch_free(rdev, scratch);
3219 return r;
3220}
3221
3222void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3223{
3224 radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1));
3225 radeon_ring_write(rdev, ib->gpu_addr);
3226 radeon_ring_write(rdev, ib->length_dw);
3227}
3228
3229int r100_ib_test(struct radeon_device *rdev)
3230{
3231 struct radeon_ib *ib;
3232 uint32_t scratch;
3233 uint32_t tmp = 0;
3234 unsigned i;
3235 int r;
3236
3237 r = radeon_scratch_get(rdev, &scratch);
3238 if (r) {
3239 DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r);
3240 return r;
3241 }
3242 WREG32(scratch, 0xCAFEDEAD);
3243 r = radeon_ib_get(rdev, &ib);
3244 if (r) {
3245 return r;
3246 }
3247 ib->ptr[0] = PACKET0(scratch, 0);
3248 ib->ptr[1] = 0xDEADBEEF;
3249 ib->ptr[2] = PACKET2(0);
3250 ib->ptr[3] = PACKET2(0);
3251 ib->ptr[4] = PACKET2(0);
3252 ib->ptr[5] = PACKET2(0);
3253 ib->ptr[6] = PACKET2(0);
3254 ib->ptr[7] = PACKET2(0);
3255 ib->length_dw = 8;
3256 r = radeon_ib_schedule(rdev, ib);
3257 if (r) {
3258 radeon_scratch_free(rdev, scratch);
3259 radeon_ib_free(rdev, &ib);
3260 return r;
3261 }
3262 r = radeon_fence_wait(ib->fence, false);
3263 if (r) {
3264 return r;
3265 }
3266 for (i = 0; i < rdev->usec_timeout; i++) {
3267 tmp = RREG32(scratch);
3268 if (tmp == 0xDEADBEEF) {
3269 break;
3270 }
3271 DRM_UDELAY(1);
3272 }
3273 if (i < rdev->usec_timeout) {
3274 DRM_INFO("ib test succeeded in %u usecs\n", i);
3275 } else {
3276 DRM_ERROR("radeon: ib test failed (sracth(0x%04X)=0x%08X)\n",
3277 scratch, tmp);
3278 r = -EINVAL;
3279 }
3280 radeon_scratch_free(rdev, scratch);
3281 radeon_ib_free(rdev, &ib);
3282 return r;
3283}
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003284
3285void r100_ib_fini(struct radeon_device *rdev)
3286{
3287 radeon_ib_pool_fini(rdev);
3288}
3289
3290int r100_ib_init(struct radeon_device *rdev)
3291{
3292 int r;
3293
3294 r = radeon_ib_pool_init(rdev);
3295 if (r) {
3296 dev_err(rdev->dev, "failled initializing IB pool (%d).\n", r);
3297 r100_ib_fini(rdev);
3298 return r;
3299 }
3300 r = r100_ib_test(rdev);
3301 if (r) {
3302 dev_err(rdev->dev, "failled testing IB (%d).\n", r);
3303 r100_ib_fini(rdev);
3304 return r;
3305 }
3306 return 0;
3307}
3308
3309void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save)
3310{
3311 /* Shutdown CP we shouldn't need to do that but better be safe than
3312 * sorry
3313 */
3314 rdev->cp.ready = false;
3315 WREG32(R_000740_CP_CSQ_CNTL, 0);
3316
3317 /* Save few CRTC registers */
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003318 save->GENMO_WT = RREG8(R_0003C2_GENMO_WT);
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003319 save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL);
3320 save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL);
3321 save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET);
3322 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3323 save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL);
3324 save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET);
3325 }
3326
3327 /* Disable VGA aperture access */
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003328 WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT);
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003329 /* Disable cursor, overlay, crtc */
3330 WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1));
3331 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL |
3332 S_000054_CRTC_DISPLAY_DIS(1));
3333 WREG32(R_000050_CRTC_GEN_CNTL,
3334 (C_000050_CRTC_CUR_EN & save->CRTC_GEN_CNTL) |
3335 S_000050_CRTC_DISP_REQ_EN_B(1));
3336 WREG32(R_000420_OV0_SCALE_CNTL,
3337 C_000420_OV0_OVERLAY_EN & RREG32(R_000420_OV0_SCALE_CNTL));
3338 WREG32(R_000260_CUR_OFFSET, C_000260_CUR_LOCK & save->CUR_OFFSET);
3339 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3340 WREG32(R_000360_CUR2_OFFSET, save->CUR2_OFFSET |
3341 S_000360_CUR2_LOCK(1));
3342 WREG32(R_0003F8_CRTC2_GEN_CNTL,
3343 (C_0003F8_CRTC2_CUR_EN & save->CRTC2_GEN_CNTL) |
3344 S_0003F8_CRTC2_DISPLAY_DIS(1) |
3345 S_0003F8_CRTC2_DISP_REQ_EN_B(1));
3346 WREG32(R_000360_CUR2_OFFSET,
3347 C_000360_CUR2_LOCK & save->CUR2_OFFSET);
3348 }
3349}
3350
3351void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save)
3352{
3353 /* Update base address for crtc */
Jerome Glissed594e462010-02-17 21:54:29 +00003354 WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003355 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
Jerome Glissed594e462010-02-17 21:54:29 +00003356 WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, rdev->mc.vram_start);
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003357 }
3358 /* Restore CRTC registers */
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003359 WREG8(R_0003C2_GENMO_WT, save->GENMO_WT);
Jerome Glisse9f022dd2009-09-11 15:35:22 +02003360 WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL);
3361 WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL);
3362 if (!(rdev->flags & RADEON_SINGLE_CRTC)) {
3363 WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL);
3364 }
3365}
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003366
3367void r100_vga_render_disable(struct radeon_device *rdev)
3368{
Jerome Glissed4550902009-10-01 10:12:06 +02003369 u32 tmp;
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003370
Jerome Glissed4550902009-10-01 10:12:06 +02003371 tmp = RREG8(R_0003C2_GENMO_WT);
Jerome Glisseca6ffc62009-10-01 10:20:52 +02003372 WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp);
3373}
Jerome Glissed4550902009-10-01 10:12:06 +02003374
3375static void r100_debugfs(struct radeon_device *rdev)
3376{
3377 int r;
3378
3379 r = r100_debugfs_mc_info_init(rdev);
3380 if (r)
3381 dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n");
3382}
3383
3384static void r100_mc_program(struct radeon_device *rdev)
3385{
3386 struct r100_mc_save save;
3387
3388 /* Stops all mc clients */
3389 r100_mc_stop(rdev, &save);
3390 if (rdev->flags & RADEON_IS_AGP) {
3391 WREG32(R_00014C_MC_AGP_LOCATION,
3392 S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) |
3393 S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
3394 WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
3395 if (rdev->family > CHIP_RV200)
3396 WREG32(R_00015C_AGP_BASE_2,
3397 upper_32_bits(rdev->mc.agp_base) & 0xff);
3398 } else {
3399 WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF);
3400 WREG32(R_000170_AGP_BASE, 0);
3401 if (rdev->family > CHIP_RV200)
3402 WREG32(R_00015C_AGP_BASE_2, 0);
3403 }
3404 /* Wait for mc idle */
3405 if (r100_mc_wait_for_idle(rdev))
3406 dev_warn(rdev->dev, "Wait for MC idle timeout.\n");
3407 /* Program MC, should be a 32bits limited address space */
3408 WREG32(R_000148_MC_FB_LOCATION,
3409 S_000148_MC_FB_START(rdev->mc.vram_start >> 16) |
3410 S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16));
3411 r100_mc_resume(rdev, &save);
3412}
3413
3414void r100_clock_startup(struct radeon_device *rdev)
3415{
3416 u32 tmp;
3417
3418 if (radeon_dynclks != -1 && radeon_dynclks)
3419 radeon_legacy_set_clock_gating(rdev, 1);
3420 /* We need to force on some of the block */
3421 tmp = RREG32_PLL(R_00000D_SCLK_CNTL);
3422 tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1);
3423 if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280))
3424 tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1);
3425 WREG32_PLL(R_00000D_SCLK_CNTL, tmp);
3426}
3427
3428static int r100_startup(struct radeon_device *rdev)
3429{
3430 int r;
3431
Alex Deucher92cde002009-12-04 10:55:12 -05003432 /* set common regs */
3433 r100_set_common_regs(rdev);
3434 /* program mc */
Jerome Glissed4550902009-10-01 10:12:06 +02003435 r100_mc_program(rdev);
3436 /* Resume clock */
3437 r100_clock_startup(rdev);
3438 /* Initialize GPU configuration (# pipes, ...) */
Jerome Glisse90aca4d2010-03-09 14:45:12 +00003439// r100_gpu_init(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003440 /* Initialize GART (initialize after TTM so we can allocate
3441 * memory through TTM but finalize after TTM) */
Dave Airlie17e15b02009-11-05 15:36:53 +10003442 r100_enable_bm(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003443 if (rdev->flags & RADEON_IS_PCI) {
3444 r = r100_pci_gart_enable(rdev);
3445 if (r)
3446 return r;
3447 }
3448 /* Enable IRQ */
Jerome Glissed4550902009-10-01 10:12:06 +02003449 r100_irq_set(rdev);
Jerome Glissecafe6602010-01-07 12:39:21 +01003450 rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL);
Jerome Glissed4550902009-10-01 10:12:06 +02003451 /* 1M ring buffer */
3452 r = r100_cp_init(rdev, 1024 * 1024);
3453 if (r) {
3454 dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
3455 return r;
3456 }
3457 r = r100_wb_init(rdev);
3458 if (r)
3459 dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
3460 r = r100_ib_init(rdev);
3461 if (r) {
3462 dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
3463 return r;
3464 }
3465 return 0;
3466}
3467
3468int r100_resume(struct radeon_device *rdev)
3469{
3470 /* Make sur GART are not working */
3471 if (rdev->flags & RADEON_IS_PCI)
3472 r100_pci_gart_disable(rdev);
3473 /* Resume clock before doing reset */
3474 r100_clock_startup(rdev);
3475 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
Jerome Glissea2d07b72010-03-09 14:45:11 +00003476 if (radeon_asic_reset(rdev)) {
Jerome Glissed4550902009-10-01 10:12:06 +02003477 dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
3478 RREG32(R_000E40_RBBM_STATUS),
3479 RREG32(R_0007C0_CP_STAT));
3480 }
3481 /* post */
3482 radeon_combios_asic_init(rdev->ddev);
3483 /* Resume clock after posting */
3484 r100_clock_startup(rdev);
Dave Airlie550e2d92009-12-09 14:15:38 +10003485 /* Initialize surface registers */
3486 radeon_surface_init(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003487 return r100_startup(rdev);
3488}
3489
3490int r100_suspend(struct radeon_device *rdev)
3491{
3492 r100_cp_disable(rdev);
3493 r100_wb_disable(rdev);
3494 r100_irq_disable(rdev);
3495 if (rdev->flags & RADEON_IS_PCI)
3496 r100_pci_gart_disable(rdev);
3497 return 0;
3498}
3499
3500void r100_fini(struct radeon_device *rdev)
3501{
Alex Deucher29fb52c2010-03-11 10:01:17 -05003502 radeon_pm_fini(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003503 r100_cp_fini(rdev);
3504 r100_wb_fini(rdev);
3505 r100_ib_fini(rdev);
3506 radeon_gem_fini(rdev);
3507 if (rdev->flags & RADEON_IS_PCI)
3508 r100_pci_gart_fini(rdev);
Jerome Glissed0269ed2010-01-07 16:08:32 +01003509 radeon_agp_fini(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003510 radeon_irq_kms_fini(rdev);
3511 radeon_fence_driver_fini(rdev);
Jerome Glisse4c788672009-11-20 14:29:23 +01003512 radeon_bo_fini(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003513 radeon_atombios_fini(rdev);
3514 kfree(rdev->bios);
3515 rdev->bios = NULL;
3516}
3517
Jerome Glissed4550902009-10-01 10:12:06 +02003518int r100_init(struct radeon_device *rdev)
3519{
3520 int r;
3521
Jerome Glissed4550902009-10-01 10:12:06 +02003522 /* Register debugfs file specific to this group of asics */
3523 r100_debugfs(rdev);
3524 /* Disable VGA */
3525 r100_vga_render_disable(rdev);
3526 /* Initialize scratch registers */
3527 radeon_scratch_init(rdev);
3528 /* Initialize surface registers */
3529 radeon_surface_init(rdev);
3530 /* TODO: disable VGA need to use VGA request */
3531 /* BIOS*/
3532 if (!radeon_get_bios(rdev)) {
3533 if (ASIC_IS_AVIVO(rdev))
3534 return -EINVAL;
3535 }
3536 if (rdev->is_atom_bios) {
3537 dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n");
3538 return -EINVAL;
3539 } else {
3540 r = radeon_combios_init(rdev);
3541 if (r)
3542 return r;
3543 }
3544 /* Reset gpu before posting otherwise ATOM will enter infinite loop */
Jerome Glissea2d07b72010-03-09 14:45:11 +00003545 if (radeon_asic_reset(rdev)) {
Jerome Glissed4550902009-10-01 10:12:06 +02003546 dev_warn(rdev->dev,
3547 "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
3548 RREG32(R_000E40_RBBM_STATUS),
3549 RREG32(R_0007C0_CP_STAT));
3550 }
3551 /* check if cards are posted or not */
Dave Airlie72542d72009-12-01 14:06:31 +10003552 if (radeon_boot_test_post_card(rdev) == false)
3553 return -EINVAL;
Jerome Glissed4550902009-10-01 10:12:06 +02003554 /* Set asic errata */
3555 r100_errata(rdev);
3556 /* Initialize clocks */
3557 radeon_get_clock_info(rdev->ddev);
Rafał Miłecki62340772009-12-15 21:46:58 +01003558 /* Initialize power management */
3559 radeon_pm_init(rdev);
Jerome Glissed594e462010-02-17 21:54:29 +00003560 /* initialize AGP */
3561 if (rdev->flags & RADEON_IS_AGP) {
3562 r = radeon_agp_init(rdev);
3563 if (r) {
3564 radeon_agp_disable(rdev);
3565 }
3566 }
3567 /* initialize VRAM */
3568 r100_mc_init(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003569 /* Fence driver */
3570 r = radeon_fence_driver_init(rdev);
3571 if (r)
3572 return r;
3573 r = radeon_irq_kms_init(rdev);
3574 if (r)
3575 return r;
3576 /* Memory manager */
Jerome Glisse4c788672009-11-20 14:29:23 +01003577 r = radeon_bo_init(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003578 if (r)
3579 return r;
3580 if (rdev->flags & RADEON_IS_PCI) {
3581 r = r100_pci_gart_init(rdev);
3582 if (r)
3583 return r;
3584 }
3585 r100_set_safe_registers(rdev);
3586 rdev->accel_working = true;
3587 r = r100_startup(rdev);
3588 if (r) {
3589 /* Somethings want wront with the accel init stop accel */
3590 dev_err(rdev->dev, "Disabling GPU acceleration\n");
Jerome Glissed4550902009-10-01 10:12:06 +02003591 r100_cp_fini(rdev);
3592 r100_wb_fini(rdev);
3593 r100_ib_fini(rdev);
Jerome Glisse655efd32010-02-02 11:51:45 +01003594 radeon_irq_kms_fini(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003595 if (rdev->flags & RADEON_IS_PCI)
3596 r100_pci_gart_fini(rdev);
Jerome Glissed4550902009-10-01 10:12:06 +02003597 rdev->accel_working = false;
3598 }
3599 return 0;
3600}