Rev 1430 | Rev 2005 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1430 | Rev 1963 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * Authors: Dave Airlie |
24 | * Authors: Dave Airlie |
25 | * Alex Deucher |
25 | * Alex Deucher |
26 | * Jerome Glisse |
26 | * Jerome Glisse |
27 | */ |
27 | */ |
28 | #include |
28 | #include |
- | 29 | #include |
|
29 | #include "drmP.h" |
30 | #include "drmP.h" |
30 | #include "drm.h" |
31 | #include "drm.h" |
31 | #include "radeon_drm.h" |
32 | #include "radeon_drm.h" |
32 | #include "radeon_reg.h" |
33 | #include "radeon_reg.h" |
33 | #include "radeon.h" |
34 | #include "radeon.h" |
- | 35 | #include "radeon_asic.h" |
|
34 | #include "r100d.h" |
36 | #include "r100d.h" |
35 | #include "rs100d.h" |
37 | #include "rs100d.h" |
36 | #include "rv200d.h" |
38 | #include "rv200d.h" |
37 | #include "rv250d.h" |
39 | #include "rv250d.h" |
- | 40 | #include "atom.h" |
|
Line 38... | Line 41... | ||
38 | 41 | ||
Line 39... | Line 42... | ||
39 | #include |
42 | #include |
40 | 43 | ||
Line 61... | Line 64... | ||
61 | 64 | ||
62 | /* This files gather functions specifics to: |
65 | /* This files gather functions specifics to: |
63 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
66 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
Line -... | Line 67... | ||
- | 67 | */ |
|
- | 68 | ||
- | 69 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
|
- | 70 | { |
|
- | 71 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
|
- | 72 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; |
|
- | 73 | ||
- | 74 | /* Lock the graphics update lock */ |
|
- | 75 | /* update the scanout addresses */ |
|
- | 76 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); |
|
- | 77 | ||
- | 78 | /* Wait for update_pending to go high. */ |
|
- | 79 | while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); |
|
- | 80 | DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); |
|
- | 81 | ||
- | 82 | /* Unlock the lock, so double-buffering can take place inside vblank */ |
|
- | 83 | tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK; |
|
- | 84 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); |
|
- | 85 | ||
- | 86 | /* Return current update_pending status: */ |
|
- | 87 | return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; |
|
- | 88 | } |
|
- | 89 | bool r100_gui_idle(struct radeon_device *rdev) |
|
- | 90 | { |
|
- | 91 | if (RREG32(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE) |
|
- | 92 | return false; |
|
- | 93 | else |
|
- | 94 | return true; |
|
64 | */ |
95 | } |
65 | 96 | ||
66 | /* hpd for digital panel detect/disconnect */ |
97 | /* hpd for digital panel detect/disconnect */ |
67 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
98 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
Line 167... | Line 198... | ||
167 | int r100_pci_gart_init(struct radeon_device *rdev) |
198 | int r100_pci_gart_init(struct radeon_device *rdev) |
168 | { |
199 | { |
169 | int r; |
200 | int r; |
Line 170... | Line 201... | ||
170 | 201 | ||
171 | if (rdev->gart.table.ram.ptr) { |
202 | if (rdev->gart.table.ram.ptr) { |
172 | WARN(1, "R100 PCI GART already initialized.\n"); |
203 | WARN(1, "R100 PCI GART already initialized\n"); |
173 | return 0; |
204 | return 0; |
174 | } |
205 | } |
175 | /* Initialize common gart structure */ |
206 | /* Initialize common gart structure */ |
176 | r = radeon_gart_init(rdev); |
207 | r = radeon_gart_init(rdev); |
Line 231... | Line 262... | ||
231 | return 0; |
262 | return 0; |
232 | } |
263 | } |
Line 233... | Line 264... | ||
233 | 264 | ||
234 | void r100_pci_gart_fini(struct radeon_device *rdev) |
265 | void r100_pci_gart_fini(struct radeon_device *rdev) |
- | 266 | { |
|
235 | { |
267 | radeon_gart_fini(rdev); |
236 | r100_pci_gart_disable(rdev); |
268 | r100_pci_gart_disable(rdev); |
237 | radeon_gart_table_ram_free(rdev); |
- | |
238 | radeon_gart_fini(rdev); |
269 | radeon_gart_table_ram_free(rdev); |
Line 239... | Line 270... | ||
239 | } |
270 | } |
240 | 271 | ||
Line 248... | Line 279... | ||
248 | mdelay(1); |
279 | mdelay(1); |
249 | tmp = RREG32(R_000044_GEN_INT_STATUS); |
280 | tmp = RREG32(R_000044_GEN_INT_STATUS); |
250 | WREG32(R_000044_GEN_INT_STATUS, tmp); |
281 | WREG32(R_000044_GEN_INT_STATUS, tmp); |
251 | } |
282 | } |
Line -... | Line 283... | ||
- | 283 | ||
252 | 284 | #if 0 |
|
253 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
285 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
254 | { |
286 | { |
255 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
287 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
256 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
288 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
257 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
289 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
Line -... | Line 290... | ||
- | 290 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
|
- | 291 | ||
- | 292 | /* the interrupt works, but the status bit is permanently asserted */ |
|
- | 293 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { |
|
- | 294 | if (!rdev->irq.gui_idle_acked) |
|
- | 295 | irq_mask |= RADEON_GUI_IDLE_STAT; |
|
258 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
296 | } |
259 | 297 | ||
260 | if (irqs) { |
298 | if (irqs) { |
261 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
299 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
262 | } |
300 | } |
Line -... | Line 301... | ||
- | 301 | return irqs & irq_mask; |
|
- | 302 | } |
|
Line 263... | Line 303... | ||
263 | return irqs & irq_mask; |
303 | |
264 | } |
304 | #endif |
265 | 305 | ||
266 | 306 | ||
Line 297... | Line 337... | ||
297 | radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); |
337 | radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); |
298 | radeon_ring_write(rdev, RADEON_SW_INT_FIRE); |
338 | radeon_ring_write(rdev, RADEON_SW_INT_FIRE); |
299 | } |
339 | } |
Line 300... | Line 340... | ||
300 | 340 | ||
301 | #if 0 |
- | |
302 | /* |
- | |
303 | * Writeback |
- | |
304 | */ |
- | |
305 | int r100_wb_init(struct radeon_device *rdev) |
- | |
306 | { |
- | |
307 | int r; |
- | |
308 | - | ||
309 | if (rdev->wb.wb_obj == NULL) { |
- | |
310 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, |
- | |
311 | RADEON_GEM_DOMAIN_GTT, |
- | |
312 | &rdev->wb.wb_obj); |
- | |
313 | if (r) { |
- | |
314 | dev_err(rdev->dev, "(%d) create WB buffer failed\n", r); |
- | |
315 | return r; |
- | |
316 | } |
- | |
317 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
- | |
318 | if (unlikely(r != 0)) |
- | |
319 | return r; |
- | |
320 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, |
- | |
321 | &rdev->wb.gpu_addr); |
- | |
322 | if (r) { |
- | |
323 | dev_err(rdev->dev, "(%d) pin WB buffer failed\n", r); |
- | |
324 | radeon_bo_unreserve(rdev->wb.wb_obj); |
- | |
325 | return r; |
- | |
326 | } |
- | |
327 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); |
- | |
328 | radeon_bo_unreserve(rdev->wb.wb_obj); |
- | |
329 | if (r) { |
- | |
330 | dev_err(rdev->dev, "(%d) map WB buffer failed\n", r); |
- | |
331 | return r; |
- | |
332 | } |
- | |
333 | } |
- | |
334 | WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr); |
- | |
335 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
- | |
336 | S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + 1024) >> 2)); |
- | |
337 | WREG32(R_000770_SCRATCH_UMSK, 0xff); |
- | |
338 | return 0; |
- | |
339 | } |
- | |
340 | - | ||
341 | void r100_wb_disable(struct radeon_device *rdev) |
- | |
342 | { |
- | |
343 | WREG32(R_000770_SCRATCH_UMSK, 0); |
- | |
344 | } |
- | |
345 | - | ||
346 | void r100_wb_fini(struct radeon_device *rdev) |
- | |
347 | { |
- | |
348 | int r; |
- | |
349 | - | ||
350 | r100_wb_disable(rdev); |
- | |
351 | if (rdev->wb.wb_obj) { |
- | |
352 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
- | |
353 | if (unlikely(r != 0)) { |
- | |
354 | dev_err(rdev->dev, "(%d) can't finish WB\n", r); |
- | |
355 | return; |
- | |
356 | } |
- | |
357 | radeon_bo_kunmap(rdev->wb.wb_obj); |
- | |
358 | radeon_bo_unpin(rdev->wb.wb_obj); |
- | |
359 | radeon_bo_unreserve(rdev->wb.wb_obj); |
- | |
360 | radeon_bo_unref(&rdev->wb.wb_obj); |
- | |
361 | rdev->wb.wb = NULL; |
- | |
362 | rdev->wb.wb_obj = NULL; |
- | |
363 | } |
- | |
Line 364... | Line 341... | ||
364 | } |
341 | #if 0 |
365 | 342 | ||
366 | int r100_copy_blit(struct radeon_device *rdev, |
343 | int r100_copy_blit(struct radeon_device *rdev, |
367 | uint64_t src_offset, |
344 | uint64_t src_offset, |
Line 477... | Line 454... | ||
477 | { |
454 | { |
478 | struct platform_device *pdev; |
455 | struct platform_device *pdev; |
479 | const char *fw_name = NULL; |
456 | const char *fw_name = NULL; |
480 | int err; |
457 | int err; |
Line 481... | Line 458... | ||
481 | 458 | ||
Line 482... | Line 459... | ||
482 | DRM_DEBUG("\n"); |
459 | DRM_DEBUG_KMS("\n"); |
483 | 460 | ||
484 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); |
461 | pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); |
485 | err = IS_ERR(pdev); |
462 | err = IS_ERR(pdev); |
Line 580... | Line 557... | ||
580 | int r; |
557 | int r; |
Line 581... | Line 558... | ||
581 | 558 | ||
582 | if (r100_debugfs_cp_init(rdev)) { |
559 | if (r100_debugfs_cp_init(rdev)) { |
583 | DRM_ERROR("Failed to register debugfs file for CP !\n"); |
560 | DRM_ERROR("Failed to register debugfs file for CP !\n"); |
584 | } |
- | |
585 | /* Reset CP */ |
- | |
586 | tmp = RREG32(RADEON_CP_CSQ_STAT); |
- | |
587 | if ((tmp & (1 << 31))) { |
- | |
588 | DRM_INFO("radeon: cp busy (0x%08X) resetting\n", tmp); |
- | |
589 | WREG32(RADEON_CP_CSQ_MODE, 0); |
- | |
590 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
- | |
591 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP); |
- | |
592 | tmp = RREG32(RADEON_RBBM_SOFT_RESET); |
- | |
593 | mdelay(2); |
- | |
594 | WREG32(RADEON_RBBM_SOFT_RESET, 0); |
- | |
595 | tmp = RREG32(RADEON_RBBM_SOFT_RESET); |
- | |
596 | mdelay(2); |
- | |
597 | tmp = RREG32(RADEON_CP_CSQ_STAT); |
- | |
598 | if ((tmp & (1 << 31))) { |
- | |
599 | DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp); |
- | |
600 | } |
- | |
601 | } else { |
- | |
602 | DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); |
- | |
603 | } |
- | |
604 | 561 | } |
|
605 | if (!rdev->me_fw) { |
562 | if (!rdev->me_fw) { |
606 | r = r100_cp_init_microcode(rdev); |
563 | r = r100_cp_init_microcode(rdev); |
607 | if (r) { |
564 | if (r) { |
608 | DRM_ERROR("Failed to load firmware!\n"); |
565 | DRM_ERROR("Failed to load firmware!\n"); |
Line 644... | Line 601... | ||
644 | indirect1_start = 16; |
601 | indirect1_start = 16; |
645 | /* cp setup */ |
602 | /* cp setup */ |
646 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
603 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
647 | tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
604 | tmp = (REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
648 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
605 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
649 | REG_SET(RADEON_MAX_FETCH, max_fetch) | |
606 | REG_SET(RADEON_MAX_FETCH, max_fetch)); |
650 | RADEON_RB_NO_UPDATE); |
- | |
651 | #ifdef __BIG_ENDIAN |
607 | #ifdef __BIG_ENDIAN |
652 | tmp |= RADEON_BUF_SWAP_32BIT; |
608 | tmp |= RADEON_BUF_SWAP_32BIT; |
653 | #endif |
609 | #endif |
654 | WREG32(RADEON_CP_RB_CNTL, tmp); |
610 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); |
Line 655... | Line 611... | ||
655 | 611 | ||
656 | /* Set ring address */ |
612 | /* Set ring address */ |
657 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
613 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
658 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
614 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
659 | /* Force read & write ptr to 0 */ |
615 | /* Force read & write ptr to 0 */ |
660 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); |
616 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); |
661 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
617 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
- | 618 | WREG32(RADEON_CP_RB_WPTR, 0); |
|
- | 619 | ||
- | 620 | /* set the wb address whether it's enabled or not */ |
|
- | 621 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
|
- | 622 | S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) >> 2)); |
|
- | 623 | WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET); |
|
- | 624 | ||
- | 625 | if (rdev->wb.enabled) |
|
- | 626 | WREG32(R_000770_SCRATCH_UMSK, 0xff); |
|
- | 627 | else { |
|
- | 628 | tmp |= RADEON_RB_NO_UPDATE; |
|
- | 629 | WREG32(R_000770_SCRATCH_UMSK, 0); |
|
- | 630 | } |
|
662 | WREG32(RADEON_CP_RB_WPTR, 0); |
631 | |
663 | WREG32(RADEON_CP_RB_CNTL, tmp); |
632 | WREG32(RADEON_CP_RB_CNTL, tmp); |
664 | udelay(10); |
633 | udelay(10); |
665 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
634 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
- | 635 | rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); |
|
- | 636 | /* protect against crazy HW on resume */ |
|
666 | rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); |
637 | rdev->cp.wptr &= rdev->cp.ptr_mask; |
667 | /* Set cp mode to bus mastering & enable cp*/ |
638 | /* Set cp mode to bus mastering & enable cp*/ |
668 | WREG32(RADEON_CP_CSQ_MODE, |
639 | WREG32(RADEON_CP_CSQ_MODE, |
669 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | |
640 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | |
670 | REG_SET(RADEON_INDIRECT1_START, indirect1_start)); |
641 | REG_SET(RADEON_INDIRECT1_START, indirect1_start)); |
671 | WREG32(0x718, 0); |
642 | WREG32(RADEON_CP_RB_WPTR_DELAY, 0); |
672 | WREG32(0x744, 0x00004D4D); |
643 | WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); |
673 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
644 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
674 | radeon_ring_start(rdev); |
645 | radeon_ring_start(rdev); |
675 | r = radeon_ring_test(rdev); |
646 | r = radeon_ring_test(rdev); |
676 | if (r) { |
647 | if (r) { |
677 | DRM_ERROR("radeon: cp isn't working (%d).\n", r); |
648 | DRM_ERROR("radeon: cp isn't working (%d).\n", r); |
678 | return r; |
649 | return r; |
679 | } |
650 | } |
- | 651 | rdev->cp.ready = true; |
|
680 | rdev->cp.ready = true; |
652 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
681 | return 0; |
653 | return 0; |
Line 682... | Line 654... | ||
682 | } |
654 | } |
683 | 655 | ||
Line 693... | Line 665... | ||
693 | } |
665 | } |
Line 694... | Line 666... | ||
694 | 666 | ||
695 | void r100_cp_disable(struct radeon_device *rdev) |
667 | void r100_cp_disable(struct radeon_device *rdev) |
696 | { |
668 | { |
- | 669 | /* Disable ring */ |
|
697 | /* Disable ring */ |
670 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
698 | rdev->cp.ready = false; |
671 | rdev->cp.ready = false; |
699 | WREG32(RADEON_CP_CSQ_MODE, 0); |
672 | WREG32(RADEON_CP_CSQ_MODE, 0); |
- | 673 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
|
700 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
674 | WREG32(R_000770_SCRATCH_UMSK, 0); |
701 | if (r100_gui_wait_for_idle(rdev)) { |
675 | if (r100_gui_wait_for_idle(rdev)) { |
702 | printk(KERN_WARNING "Failed to wait GUI idle while " |
676 | printk(KERN_WARNING "Failed to wait GUI idle while " |
703 | "programming pipes. Bad things might happen.\n"); |
677 | "programming pipes. Bad things might happen.\n"); |
704 | } |
678 | } |
Line 705... | Line -... | ||
705 | } |
- | |
706 | - | ||
707 | int r100_cp_reset(struct radeon_device *rdev) |
- | |
708 | { |
- | |
709 | uint32_t tmp; |
- | |
710 | bool reinit_cp; |
- | |
711 | int i; |
- | |
712 | - | ||
713 | reinit_cp = rdev->cp.ready; |
- | |
714 | rdev->cp.ready = false; |
- | |
715 | WREG32(RADEON_CP_CSQ_MODE, 0); |
- | |
716 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
- | |
717 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_CP); |
- | |
718 | (void)RREG32(RADEON_RBBM_SOFT_RESET); |
- | |
719 | udelay(200); |
- | |
720 | WREG32(RADEON_RBBM_SOFT_RESET, 0); |
- | |
721 | /* Wait to prevent race in RBBM_STATUS */ |
- | |
722 | mdelay(1); |
- | |
723 | for (i = 0; i < rdev->usec_timeout; i++) { |
- | |
724 | tmp = RREG32(RADEON_RBBM_STATUS); |
- | |
725 | if (!(tmp & (1 << 16))) { |
- | |
726 | DRM_INFO("CP reset succeed (RBBM_STATUS=0x%08X)\n", |
- | |
727 | tmp); |
- | |
728 | if (reinit_cp) { |
- | |
729 | return r100_cp_init(rdev, rdev->cp.ring_size); |
- | |
730 | } |
- | |
731 | return 0; |
- | |
732 | } |
- | |
733 | DRM_UDELAY(1); |
- | |
734 | } |
- | |
735 | tmp = RREG32(RADEON_RBBM_STATUS); |
- | |
736 | DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp); |
- | |
737 | return -1; |
- | |
738 | } |
679 | } |
739 | 680 | ||
740 | void r100_cp_commit(struct radeon_device *rdev) |
681 | void r100_cp_commit(struct radeon_device *rdev) |
741 | { |
682 | { |
742 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); |
683 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); |
Line 888... | Line 829... | ||
888 | 829 | ||
889 | /* check its a wait until and only 1 count */ |
830 | /* check its a wait until and only 1 count */ |
890 | if (waitreloc.reg != RADEON_WAIT_UNTIL || |
831 | if (waitreloc.reg != RADEON_WAIT_UNTIL || |
891 | waitreloc.count != 0) { |
832 | waitreloc.count != 0) { |
892 | DRM_ERROR("vline wait had illegal wait until segment\n"); |
833 | DRM_ERROR("vline wait had illegal wait until segment\n"); |
893 | r = -EINVAL; |
- | |
894 | return r; |
834 | return -EINVAL; |
Line 895... | Line 835... | ||
895 | } |
835 | } |
896 | 836 | ||
897 | if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) { |
837 | if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) { |
898 | DRM_ERROR("vline wait had illegal wait until\n"); |
- | |
899 | r = -EINVAL; |
838 | DRM_ERROR("vline wait had illegal wait until\n"); |
Line 900... | Line 839... | ||
900 | return r; |
839 | return -EINVAL; |
901 | } |
840 | } |
902 | 841 | ||
Line 910... | Line 849... | ||
910 | p->idx += p3reloc.count + 2; |
849 | p->idx += p3reloc.count + 2; |
Line 911... | Line 850... | ||
911 | 850 | ||
912 | header = radeon_get_ib_value(p, h_idx); |
851 | header = radeon_get_ib_value(p, h_idx); |
913 | crtc_id = radeon_get_ib_value(p, h_idx + 5); |
852 | crtc_id = radeon_get_ib_value(p, h_idx + 5); |
914 | reg = CP_PACKET0_GET_REG(header); |
- | |
915 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
853 | reg = CP_PACKET0_GET_REG(header); |
916 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); |
854 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); |
917 | if (!obj) { |
855 | if (!obj) { |
918 | DRM_ERROR("cannot find crtc %d\n", crtc_id); |
856 | DRM_ERROR("cannot find crtc %d\n", crtc_id); |
919 | r = -EINVAL; |
- | |
920 | goto out; |
857 | return -EINVAL; |
921 | } |
858 | } |
922 | crtc = obj_to_crtc(obj); |
859 | crtc = obj_to_crtc(obj); |
923 | radeon_crtc = to_radeon_crtc(crtc); |
860 | radeon_crtc = to_radeon_crtc(crtc); |
Line 937... | Line 874... | ||
937 | header &= ~R300_CP_PACKET0_REG_MASK; |
874 | header &= ~R300_CP_PACKET0_REG_MASK; |
938 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
875 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
939 | break; |
876 | break; |
940 | default: |
877 | default: |
941 | DRM_ERROR("unknown crtc reloc\n"); |
878 | DRM_ERROR("unknown crtc reloc\n"); |
942 | r = -EINVAL; |
879 | return -EINVAL; |
943 | goto out; |
- | |
944 | } |
880 | } |
945 | ib[h_idx] = header; |
881 | ib[h_idx] = header; |
946 | ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
882 | ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
947 | } |
883 | } |
948 | out: |
884 | |
949 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); |
- | |
950 | return r; |
885 | return 0; |
951 | } |
886 | } |
Line 952... | Line 887... | ||
952 | 887 | ||
953 | /** |
888 | /** |
954 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 |
889 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 |
Line 1095... | Line 1030... | ||
1095 | r100_cs_dump_packet(p, pkt); |
1030 | r100_cs_dump_packet(p, pkt); |
1096 | return r; |
1031 | return r; |
1097 | } |
1032 | } |
1098 | track->zb.robj = reloc->robj; |
1033 | track->zb.robj = reloc->robj; |
1099 | track->zb.offset = idx_value; |
1034 | track->zb.offset = idx_value; |
- | 1035 | track->zb_dirty = true; |
|
1100 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1036 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1101 | break; |
1037 | break; |
1102 | case RADEON_RB3D_COLOROFFSET: |
1038 | case RADEON_RB3D_COLOROFFSET: |
1103 | r = r100_cs_packet_next_reloc(p, &reloc); |
1039 | r = r100_cs_packet_next_reloc(p, &reloc); |
1104 | if (r) { |
1040 | if (r) { |
Line 1107... | Line 1043... | ||
1107 | r100_cs_dump_packet(p, pkt); |
1043 | r100_cs_dump_packet(p, pkt); |
1108 | return r; |
1044 | return r; |
1109 | } |
1045 | } |
1110 | track->cb[0].robj = reloc->robj; |
1046 | track->cb[0].robj = reloc->robj; |
1111 | track->cb[0].offset = idx_value; |
1047 | track->cb[0].offset = idx_value; |
- | 1048 | track->cb_dirty = true; |
|
1112 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1049 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1113 | break; |
1050 | break; |
1114 | case RADEON_PP_TXOFFSET_0: |
1051 | case RADEON_PP_TXOFFSET_0: |
1115 | case RADEON_PP_TXOFFSET_1: |
1052 | case RADEON_PP_TXOFFSET_1: |
1116 | case RADEON_PP_TXOFFSET_2: |
1053 | case RADEON_PP_TXOFFSET_2: |
Line 1122... | Line 1059... | ||
1122 | r100_cs_dump_packet(p, pkt); |
1059 | r100_cs_dump_packet(p, pkt); |
1123 | return r; |
1060 | return r; |
1124 | } |
1061 | } |
1125 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1062 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1126 | track->textures[i].robj = reloc->robj; |
1063 | track->textures[i].robj = reloc->robj; |
- | 1064 | track->tex_dirty = true; |
|
1127 | break; |
1065 | break; |
1128 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1066 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1129 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
1067 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
1130 | case RADEON_PP_CUBIC_OFFSET_T0_2: |
1068 | case RADEON_PP_CUBIC_OFFSET_T0_2: |
1131 | case RADEON_PP_CUBIC_OFFSET_T0_3: |
1069 | case RADEON_PP_CUBIC_OFFSET_T0_3: |
Line 1139... | Line 1077... | ||
1139 | return r; |
1077 | return r; |
1140 | } |
1078 | } |
1141 | track->textures[0].cube_info[i].offset = idx_value; |
1079 | track->textures[0].cube_info[i].offset = idx_value; |
1142 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1080 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1143 | track->textures[0].cube_info[i].robj = reloc->robj; |
1081 | track->textures[0].cube_info[i].robj = reloc->robj; |
- | 1082 | track->tex_dirty = true; |
|
1144 | break; |
1083 | break; |
1145 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
1084 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
1146 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
1085 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
1147 | case RADEON_PP_CUBIC_OFFSET_T1_2: |
1086 | case RADEON_PP_CUBIC_OFFSET_T1_2: |
1148 | case RADEON_PP_CUBIC_OFFSET_T1_3: |
1087 | case RADEON_PP_CUBIC_OFFSET_T1_3: |
Line 1156... | Line 1095... | ||
1156 | return r; |
1095 | return r; |
1157 | } |
1096 | } |
1158 | track->textures[1].cube_info[i].offset = idx_value; |
1097 | track->textures[1].cube_info[i].offset = idx_value; |
1159 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1098 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1160 | track->textures[1].cube_info[i].robj = reloc->robj; |
1099 | track->textures[1].cube_info[i].robj = reloc->robj; |
- | 1100 | track->tex_dirty = true; |
|
1161 | break; |
1101 | break; |
1162 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
1102 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
1163 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
1103 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
1164 | case RADEON_PP_CUBIC_OFFSET_T2_2: |
1104 | case RADEON_PP_CUBIC_OFFSET_T2_2: |
1165 | case RADEON_PP_CUBIC_OFFSET_T2_3: |
1105 | case RADEON_PP_CUBIC_OFFSET_T2_3: |
Line 1173... | Line 1113... | ||
1173 | return r; |
1113 | return r; |
1174 | } |
1114 | } |
1175 | track->textures[2].cube_info[i].offset = idx_value; |
1115 | track->textures[2].cube_info[i].offset = idx_value; |
1176 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1116 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1177 | track->textures[2].cube_info[i].robj = reloc->robj; |
1117 | track->textures[2].cube_info[i].robj = reloc->robj; |
- | 1118 | track->tex_dirty = true; |
|
1178 | break; |
1119 | break; |
1179 | case RADEON_RE_WIDTH_HEIGHT: |
1120 | case RADEON_RE_WIDTH_HEIGHT: |
1180 | track->maxy = ((idx_value >> 16) & 0x7FF); |
1121 | track->maxy = ((idx_value >> 16) & 0x7FF); |
- | 1122 | track->cb_dirty = true; |
|
- | 1123 | track->zb_dirty = true; |
|
1181 | break; |
1124 | break; |
1182 | case RADEON_RB3D_COLORPITCH: |
1125 | case RADEON_RB3D_COLORPITCH: |
1183 | r = r100_cs_packet_next_reloc(p, &reloc); |
1126 | r = r100_cs_packet_next_reloc(p, &reloc); |
1184 | if (r) { |
1127 | if (r) { |
1185 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1128 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
Line 1196... | Line 1139... | ||
1196 | tmp = idx_value & ~(0x7 << 16); |
1139 | tmp = idx_value & ~(0x7 << 16); |
1197 | tmp |= tile_flags; |
1140 | tmp |= tile_flags; |
1198 | ib[idx] = tmp; |
1141 | ib[idx] = tmp; |
Line 1199... | Line 1142... | ||
1199 | 1142 | ||
- | 1143 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
|
1200 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1144 | track->cb_dirty = true; |
1201 | break; |
1145 | break; |
1202 | case RADEON_RB3D_DEPTHPITCH: |
1146 | case RADEON_RB3D_DEPTHPITCH: |
- | 1147 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
|
1203 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
1148 | track->zb_dirty = true; |
1204 | break; |
1149 | break; |
1205 | case RADEON_RB3D_CNTL: |
1150 | case RADEON_RB3D_CNTL: |
1206 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
1151 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
1207 | case 7: |
1152 | case 7: |
Line 1223... | Line 1168... | ||
1223 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
1168 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
1224 | ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
1169 | ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
1225 | return -EINVAL; |
1170 | return -EINVAL; |
1226 | } |
1171 | } |
1227 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
1172 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
- | 1173 | track->cb_dirty = true; |
|
- | 1174 | track->zb_dirty = true; |
|
1228 | break; |
1175 | break; |
1229 | case RADEON_RB3D_ZSTENCILCNTL: |
1176 | case RADEON_RB3D_ZSTENCILCNTL: |
1230 | switch (idx_value & 0xf) { |
1177 | switch (idx_value & 0xf) { |
1231 | case 0: |
1178 | case 0: |
1232 | track->zb.cpp = 2; |
1179 | track->zb.cpp = 2; |
Line 1240... | Line 1187... | ||
1240 | track->zb.cpp = 4; |
1187 | track->zb.cpp = 4; |
1241 | break; |
1188 | break; |
1242 | default: |
1189 | default: |
1243 | break; |
1190 | break; |
1244 | } |
1191 | } |
- | 1192 | track->zb_dirty = true; |
|
1245 | break; |
1193 | break; |
1246 | case RADEON_RB3D_ZPASS_ADDR: |
1194 | case RADEON_RB3D_ZPASS_ADDR: |
1247 | r = r100_cs_packet_next_reloc(p, &reloc); |
1195 | r = r100_cs_packet_next_reloc(p, &reloc); |
1248 | if (r) { |
1196 | if (r) { |
1249 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1197 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
Line 1256... | Line 1204... | ||
1256 | case RADEON_PP_CNTL: |
1204 | case RADEON_PP_CNTL: |
1257 | { |
1205 | { |
1258 | uint32_t temp = idx_value >> 4; |
1206 | uint32_t temp = idx_value >> 4; |
1259 | for (i = 0; i < track->num_texture; i++) |
1207 | for (i = 0; i < track->num_texture; i++) |
1260 | track->textures[i].enabled = !!(temp & (1 << i)); |
1208 | track->textures[i].enabled = !!(temp & (1 << i)); |
- | 1209 | track->tex_dirty = true; |
|
1261 | } |
1210 | } |
1262 | break; |
1211 | break; |
1263 | case RADEON_SE_VF_CNTL: |
1212 | case RADEON_SE_VF_CNTL: |
1264 | track->vap_vf_cntl = idx_value; |
1213 | track->vap_vf_cntl = idx_value; |
1265 | break; |
1214 | break; |
Line 1270... | Line 1219... | ||
1270 | case RADEON_PP_TEX_SIZE_1: |
1219 | case RADEON_PP_TEX_SIZE_1: |
1271 | case RADEON_PP_TEX_SIZE_2: |
1220 | case RADEON_PP_TEX_SIZE_2: |
1272 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
1221 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
1273 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
1222 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
1274 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
1223 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
- | 1224 | track->tex_dirty = true; |
|
1275 | break; |
1225 | break; |
1276 | case RADEON_PP_TEX_PITCH_0: |
1226 | case RADEON_PP_TEX_PITCH_0: |
1277 | case RADEON_PP_TEX_PITCH_1: |
1227 | case RADEON_PP_TEX_PITCH_1: |
1278 | case RADEON_PP_TEX_PITCH_2: |
1228 | case RADEON_PP_TEX_PITCH_2: |
1279 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
1229 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
1280 | track->textures[i].pitch = idx_value + 32; |
1230 | track->textures[i].pitch = idx_value + 32; |
- | 1231 | track->tex_dirty = true; |
|
1281 | break; |
1232 | break; |
1282 | case RADEON_PP_TXFILTER_0: |
1233 | case RADEON_PP_TXFILTER_0: |
1283 | case RADEON_PP_TXFILTER_1: |
1234 | case RADEON_PP_TXFILTER_1: |
1284 | case RADEON_PP_TXFILTER_2: |
1235 | case RADEON_PP_TXFILTER_2: |
1285 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
1236 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
Line 1289... | Line 1240... | ||
1289 | if (tmp == 2 || tmp == 6) |
1240 | if (tmp == 2 || tmp == 6) |
1290 | track->textures[i].roundup_w = false; |
1241 | track->textures[i].roundup_w = false; |
1291 | tmp = (idx_value >> 27) & 0x7; |
1242 | tmp = (idx_value >> 27) & 0x7; |
1292 | if (tmp == 2 || tmp == 6) |
1243 | if (tmp == 2 || tmp == 6) |
1293 | track->textures[i].roundup_h = false; |
1244 | track->textures[i].roundup_h = false; |
- | 1245 | track->tex_dirty = true; |
|
1294 | break; |
1246 | break; |
1295 | case RADEON_PP_TXFORMAT_0: |
1247 | case RADEON_PP_TXFORMAT_0: |
1296 | case RADEON_PP_TXFORMAT_1: |
1248 | case RADEON_PP_TXFORMAT_1: |
1297 | case RADEON_PP_TXFORMAT_2: |
1249 | case RADEON_PP_TXFORMAT_2: |
1298 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
1250 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
Line 1308... | Line 1260... | ||
1308 | switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { |
1260 | switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { |
1309 | case RADEON_TXFORMAT_I8: |
1261 | case RADEON_TXFORMAT_I8: |
1310 | case RADEON_TXFORMAT_RGB332: |
1262 | case RADEON_TXFORMAT_RGB332: |
1311 | case RADEON_TXFORMAT_Y8: |
1263 | case RADEON_TXFORMAT_Y8: |
1312 | track->textures[i].cpp = 1; |
1264 | track->textures[i].cpp = 1; |
- | 1265 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
|
1313 | break; |
1266 | break; |
1314 | case RADEON_TXFORMAT_AI88: |
1267 | case RADEON_TXFORMAT_AI88: |
1315 | case RADEON_TXFORMAT_ARGB1555: |
1268 | case RADEON_TXFORMAT_ARGB1555: |
1316 | case RADEON_TXFORMAT_RGB565: |
1269 | case RADEON_TXFORMAT_RGB565: |
1317 | case RADEON_TXFORMAT_ARGB4444: |
1270 | case RADEON_TXFORMAT_ARGB4444: |
Line 1319... | Line 1272... | ||
1319 | case RADEON_TXFORMAT_YVYU422: |
1272 | case RADEON_TXFORMAT_YVYU422: |
1320 | case RADEON_TXFORMAT_SHADOW16: |
1273 | case RADEON_TXFORMAT_SHADOW16: |
1321 | case RADEON_TXFORMAT_LDUDV655: |
1274 | case RADEON_TXFORMAT_LDUDV655: |
1322 | case RADEON_TXFORMAT_DUDV88: |
1275 | case RADEON_TXFORMAT_DUDV88: |
1323 | track->textures[i].cpp = 2; |
1276 | track->textures[i].cpp = 2; |
- | 1277 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
|
1324 | break; |
1278 | break; |
1325 | case RADEON_TXFORMAT_ARGB8888: |
1279 | case RADEON_TXFORMAT_ARGB8888: |
1326 | case RADEON_TXFORMAT_RGBA8888: |
1280 | case RADEON_TXFORMAT_RGBA8888: |
1327 | case RADEON_TXFORMAT_SHADOW32: |
1281 | case RADEON_TXFORMAT_SHADOW32: |
1328 | case RADEON_TXFORMAT_LDUDUV8888: |
1282 | case RADEON_TXFORMAT_LDUDUV8888: |
1329 | track->textures[i].cpp = 4; |
1283 | track->textures[i].cpp = 4; |
- | 1284 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
|
1330 | break; |
1285 | break; |
1331 | case RADEON_TXFORMAT_DXT1: |
1286 | case RADEON_TXFORMAT_DXT1: |
1332 | track->textures[i].cpp = 1; |
1287 | track->textures[i].cpp = 1; |
1333 | track->textures[i].compress_format = R100_TRACK_COMP_DXT1; |
1288 | track->textures[i].compress_format = R100_TRACK_COMP_DXT1; |
1334 | break; |
1289 | break; |
Line 1338... | Line 1293... | ||
1338 | track->textures[i].compress_format = R100_TRACK_COMP_DXT35; |
1293 | track->textures[i].compress_format = R100_TRACK_COMP_DXT35; |
1339 | break; |
1294 | break; |
1340 | } |
1295 | } |
1341 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
1296 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
1342 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
1297 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
- | 1298 | track->tex_dirty = true; |
|
1343 | break; |
1299 | break; |
1344 | case RADEON_PP_CUBIC_FACES_0: |
1300 | case RADEON_PP_CUBIC_FACES_0: |
1345 | case RADEON_PP_CUBIC_FACES_1: |
1301 | case RADEON_PP_CUBIC_FACES_1: |
1346 | case RADEON_PP_CUBIC_FACES_2: |
1302 | case RADEON_PP_CUBIC_FACES_2: |
1347 | tmp = idx_value; |
1303 | tmp = idx_value; |
1348 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
1304 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
1349 | for (face = 0; face < 4; face++) { |
1305 | for (face = 0; face < 4; face++) { |
1350 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
1306 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
1351 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
1307 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
1352 | } |
1308 | } |
- | 1309 | track->tex_dirty = true; |
|
1353 | break; |
1310 | break; |
1354 | default: |
1311 | default: |
1355 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
1312 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
1356 | reg, idx); |
1313 | reg, idx); |
1357 | return -EINVAL; |
1314 | return -EINVAL; |
Line 1482... | Line 1439... | ||
1482 | r = r100_cs_track_check(p->rdev, track); |
1439 | r = r100_cs_track_check(p->rdev, track); |
1483 | if (r) |
1440 | if (r) |
1484 | return r; |
1441 | return r; |
1485 | break; |
1442 | break; |
1486 | /* triggers drawing using indices to vertex buffer */ |
1443 | /* triggers drawing using indices to vertex buffer */ |
- | 1444 | case PACKET3_3D_CLEAR_HIZ: |
|
- | 1445 | case PACKET3_3D_CLEAR_ZMASK: |
|
- | 1446 | if (p->rdev->hyperz_filp != p->filp) |
|
- | 1447 | return -EINVAL; |
|
- | 1448 | break; |
|
1487 | case PACKET3_NOP: |
1449 | case PACKET3_NOP: |
1488 | break; |
1450 | break; |
1489 | default: |
1451 | default: |
1490 | DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); |
1452 | DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); |
1491 | return -EINVAL; |
1453 | return -EINVAL; |
Line 1650... | Line 1612... | ||
1650 | DRM_UDELAY(1); |
1612 | DRM_UDELAY(1); |
1651 | } |
1613 | } |
1652 | return -1; |
1614 | return -1; |
1653 | } |
1615 | } |
Line 1654... | Line 1616... | ||
1654 | 1616 | ||
1655 | void r100_gpu_init(struct radeon_device *rdev) |
1617 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp) |
1656 | { |
1618 | { |
1657 | /* TODO: anythings to do here ? pipes ? */ |
1619 | lockup->last_cp_rptr = cp->rptr; |
1658 | r100_hdp_reset(rdev); |
1620 | lockup->last_jiffies = 0; //jiffies; |
Line -... | Line 1621... | ||
- | 1621 | } |
|
- | 1622 | ||
1659 | } |
1623 | /** |
- | 1624 | * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information |
|
- | 1625 | * @rdev: radeon device structure |
|
- | 1626 | * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations |
|
- | 1627 | * @cp: radeon_cp structure holding CP information |
|
- | 1628 | * |
|
- | 1629 | * We don't need to initialize the lockup tracking information as we will either |
|
- | 1630 | * have CP rptr to a different value of jiffies wrap around which will force |
|
- | 1631 | * initialization of the lockup tracking informations. |
|
- | 1632 | * |
|
- | 1633 | * A possible false positivie is if we get call after while and last_cp_rptr == |
|
- | 1634 | * the current CP rptr, even if it's unlikely it might happen. To avoid this |
|
- | 1635 | * if the elapsed time since last call is bigger than 2 second than we return |
|
- | 1636 | * false and update the tracking information. Due to this the caller must call |
|
- | 1637 | * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported |
|
- | 1638 | * the fencing code should be cautious about that. |
|
- | 1639 | * |
|
- | 1640 | * Caller should write to the ring to force CP to do something so we don't get |
|
- | 1641 | * false positive when CP is just gived nothing to do. |
|
- | 1642 | * |
|
1660 | 1643 | **/ |
|
1661 | void r100_hdp_reset(struct radeon_device *rdev) |
1644 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp) |
Line -... | Line 1645... | ||
- | 1645 | { |
|
- | 1646 | unsigned long cjiffies, elapsed; |
|
1662 | { |
1647 | |
1663 | uint32_t tmp; |
1648 | #if 0 |
1664 | 1649 | cjiffies = jiffies; |
|
1665 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; |
1650 | if (!time_after(cjiffies, lockup->last_jiffies)) { |
1666 | tmp |= (7 << 28); |
1651 | /* likely a wrap around */ |
- | 1652 | lockup->last_cp_rptr = cp->rptr; |
|
- | 1653 | lockup->last_jiffies = jiffies; |
|
- | 1654 | return false; |
|
1667 | WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE); |
1655 | } |
1668 | (void)RREG32(RADEON_HOST_PATH_CNTL); |
1656 | if (cp->rptr != lockup->last_cp_rptr) { |
- | 1657 | /* CP is still working no lockup */ |
|
- | 1658 | lockup->last_cp_rptr = cp->rptr; |
|
- | 1659 | lockup->last_jiffies = jiffies; |
|
- | 1660 | return false; |
|
- | 1661 | } |
|
- | 1662 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); |
|
- | 1663 | if (elapsed >= 10000) { |
|
- | 1664 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); |
|
- | 1665 | return true; |
|
1669 | udelay(200); |
1666 | } |
- | 1667 | #endif |
|
1670 | WREG32(RADEON_RBBM_SOFT_RESET, 0); |
1668 | |
Line 1671... | Line 1669... | ||
1671 | WREG32(RADEON_HOST_PATH_CNTL, tmp); |
1669 | /* give a chance to the GPU ... */ |
1672 | (void)RREG32(RADEON_HOST_PATH_CNTL); |
1670 | return false; |
1673 | } |
1671 | } |
1674 | 1672 | ||
Line 1675... | Line -... | ||
1675 | int r100_rb2d_reset(struct radeon_device *rdev) |
- | |
1676 | { |
- | |
1677 | uint32_t tmp; |
- | |
1678 | int i; |
- | |
1679 | - | ||
1680 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2); |
- | |
1681 | (void)RREG32(RADEON_RBBM_SOFT_RESET); |
- | |
1682 | udelay(200); |
1673 | bool r100_gpu_is_lockup(struct radeon_device *rdev) |
1683 | WREG32(RADEON_RBBM_SOFT_RESET, 0); |
1674 | { |
1684 | /* Wait to prevent race in RBBM_STATUS */ |
1675 | u32 rbbm_status; |
1685 | mdelay(1); |
- | |
1686 | for (i = 0; i < rdev->usec_timeout; i++) { |
1676 | int r; |
1687 | tmp = RREG32(RADEON_RBBM_STATUS); |
1677 | |
- | 1678 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
|
- | 1679 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
|
- | 1680 | r100_gpu_lockup_update(&rdev->config.r100.lockup, &rdev->cp); |
|
1688 | if (!(tmp & (1 << 26))) { |
1681 | return false; |
- | 1682 | } |
|
- | 1683 | /* force CP activities */ |
|
- | 1684 | r = radeon_ring_lock(rdev, 2); |
|
1689 | DRM_INFO("RB2D reset succeed (RBBM_STATUS=0x%08X)\n", |
1685 | if (!r) { |
- | 1686 | /* PACKET2 NOP */ |
|
- | 1687 | radeon_ring_write(rdev, 0x80000000); |
|
- | 1688 | radeon_ring_write(rdev, 0x80000000); |
|
- | 1689 | radeon_ring_unlock_commit(rdev); |
|
- | 1690 | } |
|
- | 1691 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
|
- | 1692 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp); |
|
- | 1693 | } |
|
- | 1694 | ||
- | 1695 | void r100_bm_disable(struct radeon_device *rdev) |
|
- | 1696 | { |
|
- | 1697 | u32 tmp; |
|
- | 1698 | ||
- | 1699 | /* disable bus mastering */ |
|
- | 1700 | tmp = RREG32(R_000030_BUS_CNTL); |
|
1690 | tmp); |
1701 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000044); |
- | 1702 | mdelay(1); |
|
1691 | return 0; |
1703 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042); |
- | 1704 | mdelay(1); |
|
1692 | } |
1705 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); |
1693 | DRM_UDELAY(1); |
1706 | tmp = RREG32(RADEON_BUS_CNTL); |
Line 1694... | Line 1707... | ||
1694 | } |
1707 | mdelay(1); |
1695 | tmp = RREG32(RADEON_RBBM_STATUS); |
1708 | tmp = PciRead16(rdev->pdev->bus, rdev->pdev->devfn, 0x4); |
- | 1709 | PciWrite16(rdev->pdev->bus, rdev->pdev->devfn, 0x4, tmp & 0xFFFB); |
|
1696 | DRM_ERROR("Failed to reset RB2D (RBBM_STATUS=0x%08X)!\n", tmp); |
1710 | mdelay(1); |
- | 1711 | } |
|
Line 1697... | Line -... | ||
1697 | return -1; |
- | |
1698 | } |
1712 | |
1699 | - | ||
1700 | int r100_gpu_reset(struct radeon_device *rdev) |
1713 | int r100_asic_reset(struct radeon_device *rdev) |
1701 | { |
1714 | { |
1702 | uint32_t status; |
- | |
1703 | - | ||
1704 | /* reset order likely matter */ |
1715 | struct r100_mc_save save; |
- | 1716 | u32 status, tmp; |
|
- | 1717 | int ret = 0; |
|
- | 1718 | ||
- | 1719 | status = RREG32(R_000E40_RBBM_STATUS); |
|
- | 1720 | if (!G_000E40_GUI_ACTIVE(status)) { |
|
- | 1721 | return 0; |
|
- | 1722 | } |
|
- | 1723 | r100_mc_stop(rdev, &save); |
|
- | 1724 | status = RREG32(R_000E40_RBBM_STATUS); |
|
- | 1725 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
|
- | 1726 | /* stop CP */ |
|
- | 1727 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
|
1705 | status = RREG32(RADEON_RBBM_STATUS); |
1728 | tmp = RREG32(RADEON_CP_RB_CNTL); |
- | 1729 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA); |
|
- | 1730 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
|
- | 1731 | WREG32(RADEON_CP_RB_WPTR, 0); |
|
- | 1732 | WREG32(RADEON_CP_RB_CNTL, tmp); |
|
- | 1733 | /* save PCI state */ |
|
- | 1734 | // pci_save_state(rdev->pdev); |
|
- | 1735 | /* disable bus mastering */ |
|
- | 1736 | r100_bm_disable(rdev); |
|
- | 1737 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_SE(1) | |
|
- | 1738 | S_0000F0_SOFT_RESET_RE(1) | |
|
- | 1739 | S_0000F0_SOFT_RESET_PP(1) | |
|
1706 | /* reset HDP */ |
1740 | S_0000F0_SOFT_RESET_RB(1)); |
- | 1741 | RREG32(R_0000F0_RBBM_SOFT_RESET); |
|
- | 1742 | mdelay(500); |
|
- | 1743 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); |
|
- | 1744 | mdelay(1); |
|
- | 1745 | status = RREG32(R_000E40_RBBM_STATUS); |
|
1707 | r100_hdp_reset(rdev); |
1746 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
- | 1747 | /* reset CP */ |
|
1708 | /* reset rb2d */ |
1748 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_CP(1)); |
- | 1749 | RREG32(R_0000F0_RBBM_SOFT_RESET); |
|
1709 | if (status & ((1 << 17) | (1 << 18) | (1 << 27))) { |
1750 | mdelay(500); |
1710 | r100_rb2d_reset(rdev); |
- | |
1711 | } |
1751 | WREG32(R_0000F0_RBBM_SOFT_RESET, 0); |
1712 | /* TODO: reset 3D engine */ |
1752 | mdelay(1); |
1713 | /* reset CP */ |
1753 | status = RREG32(R_000E40_RBBM_STATUS); |
1714 | status = RREG32(RADEON_RBBM_STATUS); |
1754 | dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); |
- | 1755 | /* restore PCI & busmastering */ |
|
1715 | if (status & (1 << 16)) { |
1756 | // pci_restore_state(rdev->pdev); |
1716 | r100_cp_reset(rdev); |
1757 | r100_enable_bm(rdev); |
1717 | } |
1758 | /* Check if GPU is idle */ |
- | 1759 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
|
1718 | /* Check if GPU is idle */ |
1760 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
1719 | status = RREG32(RADEON_RBBM_STATUS); |
1761 | dev_err(rdev->dev, "failed to reset GPU\n"); |
Line 1720... | Line 1762... | ||
1720 | if (status & RADEON_RBBM_ACTIVE) { |
1762 | rdev->gpu_lockup = true; |
1721 | DRM_ERROR("Failed to reset GPU (RBBM_STATUS=0x%08X)\n", status); |
1763 | ret = -1; |
1722 | return -1; |
1764 | } else |
1723 | } |
1765 | dev_info(rdev->dev, "GPU reset succeed\n"); |
- | 1766 | r100_mc_resume(rdev, &save); |
|
Line 1724... | Line 1767... | ||
1724 | DRM_INFO("GPU reset succeed (RBBM_STATUS=0x%08X)\n", status); |
1767 | return ret; |
1725 | return 0; |
1768 | } |
1726 | } |
1769 | |
1727 | 1770 | void r100_set_common_regs(struct radeon_device *rdev) |
|
Line 1798... | Line 1841... | ||
1798 | 1841 | ||
1799 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
1842 | WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl); |
1800 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); |
1843 | WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); |
1801 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); |
1844 | WREG32(RADEON_DAC_CNTL2, dac2_cntl); |
- | 1845 | } |
|
- | 1846 | ||
- | 1847 | /* switch PM block to ACPI mode */ |
|
- | 1848 | tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL); |
|
- | 1849 | tmp &= ~RADEON_PM_MODE_SEL; |
|
- | 1850 | WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp); |
|
1802 | } |
1851 | |
Line 1803... | Line 1852... | ||
1803 | } |
1852 | } |
1804 | 1853 | ||
1805 | /* |
1854 | /* |
Line 1881... | Line 1930... | ||
1881 | void r100_vram_init_sizes(struct radeon_device *rdev) |
1930 | void r100_vram_init_sizes(struct radeon_device *rdev) |
1882 | { |
1931 | { |
1883 | u64 config_aper_size; |
1932 | u64 config_aper_size; |
Line 1884... | Line 1933... | ||
1884 | 1933 | ||
1885 | /* work out accessible VRAM */ |
1934 | /* work out accessible VRAM */ |
1886 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
1935 | rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); |
1887 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
1936 | rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); |
1888 | rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); |
1937 | rdev->mc.visible_vram_size = r100_get_accessible_vram(rdev); |
1889 | /* FIXME we don't use the second aperture yet when we could use it */ |
1938 | /* FIXME we don't use the second aperture yet when we could use it */ |
1890 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
1939 | if (rdev->mc.visible_vram_size > rdev->mc.aper_size) |
1891 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
1940 | rdev->mc.visible_vram_size = rdev->mc.aper_size; |
Line 1907... | Line 1956... | ||
1907 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
1956 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
1908 | } |
1957 | } |
1909 | /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - |
1958 | /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - |
1910 | * Novell bug 204882 + along with lots of ubuntu ones |
1959 | * Novell bug 204882 + along with lots of ubuntu ones |
1911 | */ |
1960 | */ |
- | 1961 | if (rdev->mc.aper_size > config_aper_size) |
|
- | 1962 | config_aper_size = rdev->mc.aper_size; |
|
- | 1963 | ||
1912 | if (config_aper_size > rdev->mc.real_vram_size) |
1964 | if (config_aper_size > rdev->mc.real_vram_size) |
1913 | rdev->mc.mc_vram_size = config_aper_size; |
1965 | rdev->mc.mc_vram_size = config_aper_size; |
1914 | else |
1966 | else |
1915 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
1967 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
1916 | } |
1968 | } |
1917 | /* FIXME remove this once we support unmappable VRAM */ |
- | |
1918 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { |
- | |
1919 | rdev->mc.mc_vram_size = rdev->mc.aper_size; |
- | |
1920 | rdev->mc.real_vram_size = rdev->mc.aper_size; |
- | |
1921 | } |
- | |
1922 | } |
1969 | } |
Line 1923... | Line 1970... | ||
1923 | 1970 | ||
1924 | void r100_vga_set_state(struct radeon_device *rdev, bool state) |
1971 | void r100_vga_set_state(struct radeon_device *rdev, bool state) |
1925 | { |
1972 | { |
Line 1926... | Line 1973... | ||
1926 | uint32_t temp; |
1973 | uint32_t temp; |
1927 | 1974 | ||
1928 | temp = RREG32(RADEON_CONFIG_CNTL); |
1975 | temp = RREG32(RADEON_CONFIG_CNTL); |
1929 | if (state == false) { |
1976 | if (state == false) { |
1930 | temp &= ~(1<<8); |
1977 | temp &= ~RADEON_CFG_VGA_RAM_EN; |
1931 | temp |= (1<<9); |
1978 | temp |= RADEON_CFG_VGA_IO_DIS; |
1932 | } else { |
1979 | } else { |
1933 | temp &= ~(1<<9); |
1980 | temp &= ~RADEON_CFG_VGA_IO_DIS; |
1934 | } |
1981 | } |
Line 1935... | Line 1982... | ||
1935 | WREG32(RADEON_CONFIG_CNTL, temp); |
1982 | WREG32(RADEON_CONFIG_CNTL, temp); |
Line 1943... | Line 1990... | ||
1943 | r100_vram_init_sizes(rdev); |
1990 | r100_vram_init_sizes(rdev); |
1944 | base = rdev->mc.aper_base; |
1991 | base = rdev->mc.aper_base; |
1945 | if (rdev->flags & RADEON_IS_IGP) |
1992 | if (rdev->flags & RADEON_IS_IGP) |
1946 | base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; |
1993 | base = (RREG32(RADEON_NB_TOM) & 0xffff) << 16; |
1947 | radeon_vram_location(rdev, &rdev->mc, base); |
1994 | radeon_vram_location(rdev, &rdev->mc, base); |
- | 1995 | rdev->mc.gtt_base_align = 0; |
|
1948 | if (!(rdev->flags & RADEON_IS_AGP)) |
1996 | if (!(rdev->flags & RADEON_IS_AGP)) |
1949 | radeon_gtt_location(rdev, &rdev->mc); |
1997 | radeon_gtt_location(rdev, &rdev->mc); |
- | 1998 | radeon_update_bandwidth_info(rdev); |
|
1950 | } |
1999 | } |
Line 1951... | Line 2000... | ||
1951 | 2000 | ||
1952 | 2001 | ||
1953 | /* |
2002 | /* |
1954 | * Indirect registers accessor |
2003 | * Indirect registers accessor |
1955 | */ |
2004 | */ |
1956 | void r100_pll_errata_after_index(struct radeon_device *rdev) |
2005 | void r100_pll_errata_after_index(struct radeon_device *rdev) |
1957 | { |
- | |
1958 | if (!(rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS)) { |
- | |
1959 | return; |
2006 | { |
1960 | } |
2007 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DUMMYREADS) { |
1961 | (void)RREG32(RADEON_CLOCK_CNTL_DATA); |
2008 | (void)RREG32(RADEON_CLOCK_CNTL_DATA); |
- | 2009 | (void)RREG32(RADEON_CRTC_GEN_CNTL); |
|
Line 1962... | Line 2010... | ||
1962 | (void)RREG32(RADEON_CRTC_GEN_CNTL); |
2010 | } |
1963 | } |
2011 | } |
1964 | 2012 | ||
1965 | static void r100_pll_errata_after_data(struct radeon_device *rdev) |
2013 | static void r100_pll_errata_after_data(struct radeon_device *rdev) |
Line 2195... | Line 2243... | ||
2195 | uint32_t offset, uint32_t obj_size) |
2243 | uint32_t offset, uint32_t obj_size) |
2196 | { |
2244 | { |
2197 | int surf_index = reg * 16; |
2245 | int surf_index = reg * 16; |
2198 | int flags = 0; |
2246 | int flags = 0; |
Line 2199... | Line -... | ||
2199 | - | ||
2200 | /* r100/r200 divide by 16 */ |
- | |
2201 | if (rdev->family < CHIP_R300) |
- | |
2202 | flags = pitch / 16; |
- | |
2203 | else |
- | |
2204 | flags = pitch / 8; |
- | |
2205 | 2247 | ||
2206 | if (rdev->family <= CHIP_RS200) { |
2248 | if (rdev->family <= CHIP_RS200) { |
2207 | if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
2249 | if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
2208 | == (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
2250 | == (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
2209 | flags |= RADEON_SURF_TILE_COLOR_BOTH; |
2251 | flags |= RADEON_SURF_TILE_COLOR_BOTH; |
Line 2224... | Line 2266... | ||
2224 | if (tiling_flags & RADEON_TILING_SWAP_16BIT) |
2266 | if (tiling_flags & RADEON_TILING_SWAP_16BIT) |
2225 | flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP; |
2267 | flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP; |
2226 | if (tiling_flags & RADEON_TILING_SWAP_32BIT) |
2268 | if (tiling_flags & RADEON_TILING_SWAP_32BIT) |
2227 | flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP; |
2269 | flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP; |
Line -... | Line 2270... | ||
- | 2270 | ||
- | 2271 | /* when we aren't tiling the pitch seems to needs to be furtherdivided down. - tested on power5 + rn50 server */ |
|
- | 2272 | if (tiling_flags & (RADEON_TILING_SWAP_16BIT | RADEON_TILING_SWAP_32BIT)) { |
|
- | 2273 | if (!(tiling_flags & (RADEON_TILING_MACRO | RADEON_TILING_MICRO))) |
|
- | 2274 | if (ASIC_IS_RN50(rdev)) |
|
- | 2275 | pitch /= 16; |
|
- | 2276 | } |
|
- | 2277 | ||
- | 2278 | /* r100/r200 divide by 16 */ |
|
- | 2279 | if (rdev->family < CHIP_R300) |
|
- | 2280 | flags |= pitch / 16; |
|
- | 2281 | else |
|
- | 2282 | flags |= pitch / 8; |
|
- | 2283 | ||
2228 | 2284 | ||
2229 | DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); |
2285 | DRM_DEBUG_KMS("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); |
2230 | WREG32(RADEON_SURFACE0_INFO + surf_index, flags); |
2286 | WREG32(RADEON_SURFACE0_INFO + surf_index, flags); |
2231 | WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); |
2287 | WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); |
2232 | WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); |
2288 | WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); |
2233 | return 0; |
2289 | return 0; |
Line 2244... | Line 2300... | ||
2244 | fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff; |
2300 | fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff; |
2245 | fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff; |
2301 | fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff; |
2246 | fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; |
2302 | fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; |
2247 | uint32_t temp, data, mem_trcd, mem_trp, mem_tras; |
2303 | uint32_t temp, data, mem_trcd, mem_trp, mem_tras; |
2248 | fixed20_12 memtcas_ff[8] = { |
2304 | fixed20_12 memtcas_ff[8] = { |
2249 | fixed_init(1), |
2305 | dfixed_init(1), |
2250 | fixed_init(2), |
2306 | dfixed_init(2), |
2251 | fixed_init(3), |
2307 | dfixed_init(3), |
2252 | fixed_init(0), |
2308 | dfixed_init(0), |
2253 | fixed_init_half(1), |
2309 | dfixed_init_half(1), |
2254 | fixed_init_half(2), |
2310 | dfixed_init_half(2), |
2255 | fixed_init(0), |
2311 | dfixed_init(0), |
2256 | }; |
2312 | }; |
2257 | fixed20_12 memtcas_rs480_ff[8] = { |
2313 | fixed20_12 memtcas_rs480_ff[8] = { |
2258 | fixed_init(0), |
2314 | dfixed_init(0), |
2259 | fixed_init(1), |
2315 | dfixed_init(1), |
2260 | fixed_init(2), |
2316 | dfixed_init(2), |
2261 | fixed_init(3), |
2317 | dfixed_init(3), |
2262 | fixed_init(0), |
2318 | dfixed_init(0), |
2263 | fixed_init_half(1), |
2319 | dfixed_init_half(1), |
2264 | fixed_init_half(2), |
2320 | dfixed_init_half(2), |
2265 | fixed_init_half(3), |
2321 | dfixed_init_half(3), |
2266 | }; |
2322 | }; |
2267 | fixed20_12 memtcas2_ff[8] = { |
2323 | fixed20_12 memtcas2_ff[8] = { |
2268 | fixed_init(0), |
2324 | dfixed_init(0), |
2269 | fixed_init(1), |
2325 | dfixed_init(1), |
2270 | fixed_init(2), |
2326 | dfixed_init(2), |
2271 | fixed_init(3), |
2327 | dfixed_init(3), |
2272 | fixed_init(4), |
2328 | dfixed_init(4), |
2273 | fixed_init(5), |
2329 | dfixed_init(5), |
2274 | fixed_init(6), |
2330 | dfixed_init(6), |
2275 | fixed_init(7), |
2331 | dfixed_init(7), |
2276 | }; |
2332 | }; |
2277 | fixed20_12 memtrbs[8] = { |
2333 | fixed20_12 memtrbs[8] = { |
2278 | fixed_init(1), |
2334 | dfixed_init(1), |
2279 | fixed_init_half(1), |
2335 | dfixed_init_half(1), |
2280 | fixed_init(2), |
2336 | dfixed_init(2), |
2281 | fixed_init_half(2), |
2337 | dfixed_init_half(2), |
2282 | fixed_init(3), |
2338 | dfixed_init(3), |
2283 | fixed_init_half(3), |
2339 | dfixed_init_half(3), |
2284 | fixed_init(4), |
2340 | dfixed_init(4), |
2285 | fixed_init_half(4) |
2341 | dfixed_init_half(4) |
2286 | }; |
2342 | }; |
2287 | fixed20_12 memtrbs_r4xx[8] = { |
2343 | fixed20_12 memtrbs_r4xx[8] = { |
2288 | fixed_init(4), |
2344 | dfixed_init(4), |
2289 | fixed_init(5), |
2345 | dfixed_init(5), |
2290 | fixed_init(6), |
2346 | dfixed_init(6), |
2291 | fixed_init(7), |
2347 | dfixed_init(7), |
2292 | fixed_init(8), |
2348 | dfixed_init(8), |
2293 | fixed_init(9), |
2349 | dfixed_init(9), |
2294 | fixed_init(10), |
2350 | dfixed_init(10), |
2295 | fixed_init(11) |
2351 | dfixed_init(11) |
2296 | }; |
2352 | }; |
2297 | fixed20_12 min_mem_eff; |
2353 | fixed20_12 min_mem_eff; |
2298 | fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; |
2354 | fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; |
2299 | fixed20_12 cur_latency_mclk, cur_latency_sclk; |
2355 | fixed20_12 cur_latency_mclk, cur_latency_sclk; |
2300 | fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate, |
2356 | fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate, |
Line 2308... | Line 2364... | ||
2308 | struct drm_display_mode *mode1 = NULL; |
2364 | struct drm_display_mode *mode1 = NULL; |
2309 | struct drm_display_mode *mode2 = NULL; |
2365 | struct drm_display_mode *mode2 = NULL; |
2310 | uint32_t pixel_bytes1 = 0; |
2366 | uint32_t pixel_bytes1 = 0; |
2311 | uint32_t pixel_bytes2 = 0; |
2367 | uint32_t pixel_bytes2 = 0; |
Line -... | Line 2368... | ||
- | 2368 | ||
- | 2369 | radeon_update_display_priority(rdev); |
|
2312 | 2370 | ||
2313 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
2371 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
2314 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
2372 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
2315 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
2373 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
2316 | } |
2374 | } |
Line 2319... | Line 2377... | ||
2319 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
2377 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
2320 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; |
2378 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; |
2321 | } |
2379 | } |
2322 | } |
2380 | } |
Line 2323... | Line 2381... | ||
2323 | 2381 | ||
2324 | min_mem_eff.full = rfixed_const_8(0); |
2382 | min_mem_eff.full = dfixed_const_8(0); |
2325 | /* get modes */ |
2383 | /* get modes */ |
2326 | if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) { |
2384 | if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) { |
2327 | uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER); |
2385 | uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER); |
2328 | mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); |
2386 | mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); |
Line 2336... | Line 2394... | ||
2336 | } |
2394 | } |
Line 2337... | Line 2395... | ||
2337 | 2395 | ||
2338 | /* |
2396 | /* |
2339 | * determine is there is enough bw for current mode |
2397 | * determine is there is enough bw for current mode |
2340 | */ |
- | |
2341 | mclk_ff.full = rfixed_const(rdev->clock.default_mclk); |
2398 | */ |
2342 | temp_ff.full = rfixed_const(100); |
2399 | sclk_ff = rdev->pm.sclk; |
2343 | mclk_ff.full = rfixed_div(mclk_ff, temp_ff); |
- | |
2344 | sclk_ff.full = rfixed_const(rdev->clock.default_sclk); |
- | |
Line 2345... | Line 2400... | ||
2345 | sclk_ff.full = rfixed_div(sclk_ff, temp_ff); |
2400 | mclk_ff = rdev->pm.mclk; |
2346 | 2401 | ||
2347 | temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); |
2402 | temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); |
Line 2348... | Line 2403... | ||
2348 | temp_ff.full = rfixed_const(temp); |
2403 | temp_ff.full = dfixed_const(temp); |
2349 | mem_bw.full = rfixed_mul(mclk_ff, temp_ff); |
2404 | mem_bw.full = dfixed_mul(mclk_ff, temp_ff); |
2350 | 2405 | ||
2351 | pix_clk.full = 0; |
2406 | pix_clk.full = 0; |
2352 | pix_clk2.full = 0; |
2407 | pix_clk2.full = 0; |
2353 | peak_disp_bw.full = 0; |
2408 | peak_disp_bw.full = 0; |
2354 | if (mode1) { |
2409 | if (mode1) { |
2355 | temp_ff.full = rfixed_const(1000); |
2410 | temp_ff.full = dfixed_const(1000); |
2356 | pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ |
2411 | pix_clk.full = dfixed_const(mode1->clock); /* convert to fixed point */ |
2357 | pix_clk.full = rfixed_div(pix_clk, temp_ff); |
2412 | pix_clk.full = dfixed_div(pix_clk, temp_ff); |
2358 | temp_ff.full = rfixed_const(pixel_bytes1); |
2413 | temp_ff.full = dfixed_const(pixel_bytes1); |
2359 | peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); |
2414 | peak_disp_bw.full += dfixed_mul(pix_clk, temp_ff); |
2360 | } |
2415 | } |
2361 | if (mode2) { |
2416 | if (mode2) { |
2362 | temp_ff.full = rfixed_const(1000); |
2417 | temp_ff.full = dfixed_const(1000); |
2363 | pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ |
2418 | pix_clk2.full = dfixed_const(mode2->clock); /* convert to fixed point */ |
2364 | pix_clk2.full = rfixed_div(pix_clk2, temp_ff); |
2419 | pix_clk2.full = dfixed_div(pix_clk2, temp_ff); |
Line 2365... | Line 2420... | ||
2365 | temp_ff.full = rfixed_const(pixel_bytes2); |
2420 | temp_ff.full = dfixed_const(pixel_bytes2); |
2366 | peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); |
2421 | peak_disp_bw.full += dfixed_mul(pix_clk2, temp_ff); |
2367 | } |
2422 | } |
2368 | 2423 | ||
2369 | mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); |
2424 | mem_bw.full = dfixed_mul(mem_bw, min_mem_eff); |
Line 2406... | Line 2461... | ||
2406 | mem_trcd = (temp & 0x7) + 1; |
2461 | mem_trcd = (temp & 0x7) + 1; |
2407 | mem_trp = ((temp >> 8) & 0x7) + 1; |
2462 | mem_trp = ((temp >> 8) & 0x7) + 1; |
2408 | mem_tras = ((temp >> 12) & 0xf) + 4; |
2463 | mem_tras = ((temp >> 12) & 0xf) + 4; |
2409 | } |
2464 | } |
2410 | /* convert to FF */ |
2465 | /* convert to FF */ |
2411 | trcd_ff.full = rfixed_const(mem_trcd); |
2466 | trcd_ff.full = dfixed_const(mem_trcd); |
2412 | trp_ff.full = rfixed_const(mem_trp); |
2467 | trp_ff.full = dfixed_const(mem_trp); |
2413 | tras_ff.full = rfixed_const(mem_tras); |
2468 | tras_ff.full = dfixed_const(mem_tras); |
Line 2414... | Line 2469... | ||
2414 | 2469 | ||
2415 | /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ |
2470 | /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ |
2416 | temp = RREG32(RADEON_MEM_SDRAM_MODE_REG); |
2471 | temp = RREG32(RADEON_MEM_SDRAM_MODE_REG); |
2417 | data = (temp & (7 << 20)) >> 20; |
2472 | data = (temp & (7 << 20)) >> 20; |
Line 2426... | Line 2481... | ||
2426 | if (rdev->family == CHIP_RS400 || |
2481 | if (rdev->family == CHIP_RS400 || |
2427 | rdev->family == CHIP_RS480) { |
2482 | rdev->family == CHIP_RS480) { |
2428 | /* extra cas latency stored in bits 23-25 0-4 clocks */ |
2483 | /* extra cas latency stored in bits 23-25 0-4 clocks */ |
2429 | data = (temp >> 23) & 0x7; |
2484 | data = (temp >> 23) & 0x7; |
2430 | if (data < 5) |
2485 | if (data < 5) |
2431 | tcas_ff.full += rfixed_const(data); |
2486 | tcas_ff.full += dfixed_const(data); |
2432 | } |
2487 | } |
Line 2433... | Line 2488... | ||
2433 | 2488 | ||
2434 | if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) { |
2489 | if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) { |
2435 | /* on the R300, Tcas is included in Trbs. |
2490 | /* on the R300, Tcas is included in Trbs. |
Line 2463... | Line 2518... | ||
2463 | 2518 | ||
Line 2464... | Line 2519... | ||
2464 | sclk_eff_ff.full = sclk_ff.full; |
2519 | sclk_eff_ff.full = sclk_ff.full; |
2465 | 2520 | ||
2466 | if (rdev->flags & RADEON_IS_AGP) { |
2521 | if (rdev->flags & RADEON_IS_AGP) { |
2467 | fixed20_12 agpmode_ff; |
2522 | fixed20_12 agpmode_ff; |
2468 | agpmode_ff.full = rfixed_const(radeon_agpmode); |
2523 | agpmode_ff.full = dfixed_const(radeon_agpmode); |
2469 | temp_ff.full = rfixed_const_666(16); |
2524 | temp_ff.full = dfixed_const_666(16); |
2470 | sclk_eff_ff.full -= rfixed_mul(agpmode_ff, temp_ff); |
2525 | sclk_eff_ff.full -= dfixed_mul(agpmode_ff, temp_ff); |
Line 2471... | Line 2526... | ||
2471 | } |
2526 | } |
2472 | /* TODO PCIE lanes may affect this - agpmode == 16?? */ |
2527 | /* TODO PCIE lanes may affect this - agpmode == 16?? */ |
2473 | 2528 | ||
2474 | if (ASIC_IS_R300(rdev)) { |
2529 | if (ASIC_IS_R300(rdev)) { |
2475 | sclk_delay_ff.full = rfixed_const(250); |
2530 | sclk_delay_ff.full = dfixed_const(250); |
2476 | } else { |
2531 | } else { |
2477 | if ((rdev->family == CHIP_RV100) || |
2532 | if ((rdev->family == CHIP_RV100) || |
2478 | rdev->flags & RADEON_IS_IGP) { |
2533 | rdev->flags & RADEON_IS_IGP) { |
2479 | if (rdev->mc.vram_is_ddr) |
2534 | if (rdev->mc.vram_is_ddr) |
2480 | sclk_delay_ff.full = rfixed_const(41); |
2535 | sclk_delay_ff.full = dfixed_const(41); |
2481 | else |
2536 | else |
2482 | sclk_delay_ff.full = rfixed_const(33); |
2537 | sclk_delay_ff.full = dfixed_const(33); |
2483 | } else { |
2538 | } else { |
2484 | if (rdev->mc.vram_width == 128) |
2539 | if (rdev->mc.vram_width == 128) |
2485 | sclk_delay_ff.full = rfixed_const(57); |
2540 | sclk_delay_ff.full = dfixed_const(57); |
2486 | else |
2541 | else |
Line 2487... | Line 2542... | ||
2487 | sclk_delay_ff.full = rfixed_const(41); |
2542 | sclk_delay_ff.full = dfixed_const(41); |
Line 2488... | Line 2543... | ||
2488 | } |
2543 | } |
2489 | } |
2544 | } |
2490 | 2545 | ||
2491 | mc_latency_sclk.full = rfixed_div(sclk_delay_ff, sclk_eff_ff); |
2546 | mc_latency_sclk.full = dfixed_div(sclk_delay_ff, sclk_eff_ff); |
2492 | 2547 | ||
2493 | if (rdev->mc.vram_is_ddr) { |
2548 | if (rdev->mc.vram_is_ddr) { |
2494 | if (rdev->mc.vram_width == 32) { |
2549 | if (rdev->mc.vram_width == 32) { |
2495 | k1.full = rfixed_const(40); |
2550 | k1.full = dfixed_const(40); |
2496 | c = 3; |
2551 | c = 3; |
2497 | } else { |
2552 | } else { |
2498 | k1.full = rfixed_const(20); |
2553 | k1.full = dfixed_const(20); |
2499 | c = 1; |
2554 | c = 1; |
Line 2500... | Line 2555... | ||
2500 | } |
2555 | } |
2501 | } else { |
2556 | } else { |
2502 | k1.full = rfixed_const(40); |
2557 | k1.full = dfixed_const(40); |
2503 | c = 3; |
2558 | c = 3; |
2504 | } |
2559 | } |
2505 | 2560 | ||
2506 | temp_ff.full = rfixed_const(2); |
2561 | temp_ff.full = dfixed_const(2); |
2507 | mc_latency_mclk.full = rfixed_mul(trcd_ff, temp_ff); |
2562 | mc_latency_mclk.full = dfixed_mul(trcd_ff, temp_ff); |
Line 2508... | Line 2563... | ||
2508 | temp_ff.full = rfixed_const(c); |
2563 | temp_ff.full = dfixed_const(c); |
2509 | mc_latency_mclk.full += rfixed_mul(tcas_ff, temp_ff); |
2564 | mc_latency_mclk.full += dfixed_mul(tcas_ff, temp_ff); |
Line 2510... | Line 2565... | ||
2510 | temp_ff.full = rfixed_const(4); |
2565 | temp_ff.full = dfixed_const(4); |
2511 | mc_latency_mclk.full += rfixed_mul(tras_ff, temp_ff); |
2566 | mc_latency_mclk.full += dfixed_mul(tras_ff, temp_ff); |
2512 | mc_latency_mclk.full += rfixed_mul(trp_ff, temp_ff); |
2567 | mc_latency_mclk.full += dfixed_mul(trp_ff, temp_ff); |
2513 | mc_latency_mclk.full += k1.full; |
2568 | mc_latency_mclk.full += k1.full; |
2514 | 2569 | ||
2515 | mc_latency_mclk.full = rfixed_div(mc_latency_mclk, mclk_ff); |
2570 | mc_latency_mclk.full = dfixed_div(mc_latency_mclk, mclk_ff); |
2516 | mc_latency_mclk.full += rfixed_div(temp_ff, sclk_eff_ff); |
2571 | mc_latency_mclk.full += dfixed_div(temp_ff, sclk_eff_ff); |
2517 | 2572 | ||
Line 2518... | Line 2573... | ||
2518 | /* |
2573 | /* |
2519 | HW cursor time assuming worst case of full size colour cursor. |
2574 | HW cursor time assuming worst case of full size colour cursor. |
2520 | */ |
2575 | */ |
2521 | temp_ff.full = rfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); |
2576 | temp_ff.full = dfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); |
2522 | temp_ff.full += trcd_ff.full; |
2577 | temp_ff.full += trcd_ff.full; |
2523 | if (temp_ff.full < tras_ff.full) |
2578 | if (temp_ff.full < tras_ff.full) |
2524 | temp_ff.full = tras_ff.full; |
2579 | temp_ff.full = tras_ff.full; |
2525 | cur_latency_mclk.full = rfixed_div(temp_ff, mclk_ff); |
2580 | cur_latency_mclk.full = dfixed_div(temp_ff, mclk_ff); |
2526 | 2581 | ||
Line 2527... | Line 2582... | ||
2527 | temp_ff.full = rfixed_const(cur_size); |
2582 | temp_ff.full = dfixed_const(cur_size); |
2528 | cur_latency_sclk.full = rfixed_div(temp_ff, sclk_eff_ff); |
2583 | cur_latency_sclk.full = dfixed_div(temp_ff, sclk_eff_ff); |
Line 2556... | Line 2611... | ||
2556 | stop_req = max_stop_req; |
2611 | stop_req = max_stop_req; |
Line 2557... | Line 2612... | ||
2557 | 2612 | ||
2558 | /* |
2613 | /* |
2559 | Find the drain rate of the display buffer. |
2614 | Find the drain rate of the display buffer. |
2560 | */ |
2615 | */ |
2561 | temp_ff.full = rfixed_const((16/pixel_bytes1)); |
2616 | temp_ff.full = dfixed_const((16/pixel_bytes1)); |
Line 2562... | Line 2617... | ||
2562 | disp_drain_rate.full = rfixed_div(pix_clk, temp_ff); |
2617 | disp_drain_rate.full = dfixed_div(pix_clk, temp_ff); |
2563 | 2618 | ||
2564 | /* |
2619 | /* |
2565 | Find the critical point of the display buffer. |
2620 | Find the critical point of the display buffer. |
2566 | */ |
2621 | */ |
Line 2567... | Line 2622... | ||
2567 | crit_point_ff.full = rfixed_mul(disp_drain_rate, disp_latency); |
2622 | crit_point_ff.full = dfixed_mul(disp_drain_rate, disp_latency); |
Line 2568... | Line 2623... | ||
2568 | crit_point_ff.full += rfixed_const_half(0); |
2623 | crit_point_ff.full += dfixed_const_half(0); |
2569 | 2624 | ||
2570 | critical_point = rfixed_trunc(crit_point_ff); |
2625 | critical_point = dfixed_trunc(crit_point_ff); |
Line 2621... | Line 2676... | ||
2621 | (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) | |
2676 | (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) | |
2622 | (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT))); |
2677 | (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT))); |
2623 | } |
2678 | } |
2624 | #endif |
2679 | #endif |
Line 2625... | Line 2680... | ||
2625 | 2680 | ||
2626 | DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n", |
2681 | DRM_DEBUG_KMS("GRPH_BUFFER_CNTL from to %x\n", |
2627 | /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ |
2682 | /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ |
2628 | (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); |
2683 | (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); |
Line 2629... | Line 2684... | ||
2629 | } |
2684 | } |
Line 2636... | Line 2691... | ||
2636 | stop_req = max_stop_req; |
2691 | stop_req = max_stop_req; |
Line 2637... | Line 2692... | ||
2637 | 2692 | ||
2638 | /* |
2693 | /* |
2639 | Find the drain rate of the display buffer. |
2694 | Find the drain rate of the display buffer. |
2640 | */ |
2695 | */ |
2641 | temp_ff.full = rfixed_const((16/pixel_bytes2)); |
2696 | temp_ff.full = dfixed_const((16/pixel_bytes2)); |
Line 2642... | Line 2697... | ||
2642 | disp_drain_rate2.full = rfixed_div(pix_clk2, temp_ff); |
2697 | disp_drain_rate2.full = dfixed_div(pix_clk2, temp_ff); |
2643 | 2698 | ||
2644 | grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL); |
2699 | grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL); |
2645 | grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK); |
2700 | grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK); |
Line 2658... | Line 2713... | ||
2658 | if ((rdev->family == CHIP_RS100) || |
2713 | if ((rdev->family == CHIP_RS100) || |
2659 | (rdev->family == CHIP_RS200)) |
2714 | (rdev->family == CHIP_RS200)) |
2660 | critical_point2 = 0; |
2715 | critical_point2 = 0; |
2661 | else { |
2716 | else { |
2662 | temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128; |
2717 | temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128; |
2663 | temp_ff.full = rfixed_const(temp); |
2718 | temp_ff.full = dfixed_const(temp); |
2664 | temp_ff.full = rfixed_mul(mclk_ff, temp_ff); |
2719 | temp_ff.full = dfixed_mul(mclk_ff, temp_ff); |
2665 | if (sclk_ff.full < temp_ff.full) |
2720 | if (sclk_ff.full < temp_ff.full) |
2666 | temp_ff.full = sclk_ff.full; |
2721 | temp_ff.full = sclk_ff.full; |
Line 2667... | Line 2722... | ||
2667 | 2722 | ||
Line 2668... | Line 2723... | ||
2668 | read_return_rate.full = temp_ff.full; |
2723 | read_return_rate.full = temp_ff.full; |
2669 | 2724 | ||
2670 | if (mode1) { |
2725 | if (mode1) { |
2671 | temp_ff.full = read_return_rate.full - disp_drain_rate.full; |
2726 | temp_ff.full = read_return_rate.full - disp_drain_rate.full; |
2672 | time_disp1_drop_priority.full = rfixed_div(crit_point_ff, temp_ff); |
2727 | time_disp1_drop_priority.full = dfixed_div(crit_point_ff, temp_ff); |
2673 | } else { |
2728 | } else { |
2674 | time_disp1_drop_priority.full = 0; |
2729 | time_disp1_drop_priority.full = 0; |
2675 | } |
2730 | } |
2676 | crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; |
2731 | crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; |
Line 2677... | Line 2732... | ||
2677 | crit_point_ff.full = rfixed_mul(crit_point_ff, disp_drain_rate2); |
2732 | crit_point_ff.full = dfixed_mul(crit_point_ff, disp_drain_rate2); |
Line 2678... | Line 2733... | ||
2678 | crit_point_ff.full += rfixed_const_half(0); |
2733 | crit_point_ff.full += dfixed_const_half(0); |
2679 | 2734 | ||
2680 | critical_point2 = rfixed_trunc(crit_point_ff); |
2735 | critical_point2 = dfixed_trunc(crit_point_ff); |
Line 2717... | Line 2772... | ||
2717 | WREG32(RS400_DISP2_REQ_CNTL2, 0x2749D000); |
2772 | WREG32(RS400_DISP2_REQ_CNTL2, 0x2749D000); |
2718 | WREG32(RS400_DMIF_MEM_CNTL1, 0x29CA71DC); |
2773 | WREG32(RS400_DMIF_MEM_CNTL1, 0x29CA71DC); |
2719 | WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); |
2774 | WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); |
2720 | } |
2775 | } |
Line 2721... | Line 2776... | ||
2721 | 2776 | ||
2722 | DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n", |
2777 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", |
2723 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
2778 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
2724 | } |
2779 | } |
Line -... | Line 2780... | ||
- | 2780 | } |
|
- | 2781 | ||
- | 2782 | #if 0 |
|
- | 2783 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) |
|
- | 2784 | { |
|
- | 2785 | DRM_ERROR("pitch %d\n", t->pitch); |
|
- | 2786 | DRM_ERROR("use_pitch %d\n", t->use_pitch); |
|
- | 2787 | DRM_ERROR("width %d\n", t->width); |
|
- | 2788 | DRM_ERROR("width_11 %d\n", t->width_11); |
|
- | 2789 | DRM_ERROR("height %d\n", t->height); |
|
- | 2790 | DRM_ERROR("height_11 %d\n", t->height_11); |
|
- | 2791 | DRM_ERROR("num levels %d\n", t->num_levels); |
|
- | 2792 | DRM_ERROR("depth %d\n", t->txdepth); |
|
- | 2793 | DRM_ERROR("bpp %d\n", t->cpp); |
|
- | 2794 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); |
|
- | 2795 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); |
|
- | 2796 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); |
|
- | 2797 | DRM_ERROR("compress format %d\n", t->compress_format); |
|
- | 2798 | } |
|
- | 2799 | ||
- | 2800 | static int r100_track_compress_size(int compress_format, int w, int h) |
|
- | 2801 | { |
|
- | 2802 | int block_width, block_height, block_bytes; |
|
- | 2803 | int wblocks, hblocks; |
|
- | 2804 | int min_wblocks; |
|
- | 2805 | int sz; |
|
- | 2806 | ||
- | 2807 | block_width = 4; |
|
- | 2808 | block_height = 4; |
|
- | 2809 | ||
- | 2810 | switch (compress_format) { |
|
- | 2811 | case R100_TRACK_COMP_DXT1: |
|
- | 2812 | block_bytes = 8; |
|
- | 2813 | min_wblocks = 4; |
|
- | 2814 | break; |
|
- | 2815 | default: |
|
- | 2816 | case R100_TRACK_COMP_DXT35: |
|
- | 2817 | block_bytes = 16; |
|
- | 2818 | min_wblocks = 2; |
|
- | 2819 | break; |
|
- | 2820 | } |
|
- | 2821 | ||
- | 2822 | hblocks = (h + block_height - 1) / block_height; |
|
- | 2823 | wblocks = (w + block_width - 1) / block_width; |
|
- | 2824 | if (wblocks < min_wblocks) |
|
- | 2825 | wblocks = min_wblocks; |
|
- | 2826 | sz = wblocks * hblocks * block_bytes; |
|
- | 2827 | return sz; |
|
- | 2828 | } |
|
- | 2829 | ||
- | 2830 | static int r100_cs_track_cube(struct radeon_device *rdev, |
|
- | 2831 | struct r100_cs_track *track, unsigned idx) |
|
- | 2832 | { |
|
- | 2833 | unsigned face, w, h; |
|
- | 2834 | struct radeon_bo *cube_robj; |
|
- | 2835 | unsigned long size; |
|
- | 2836 | unsigned compress_format = track->textures[idx].compress_format; |
|
- | 2837 | ||
- | 2838 | for (face = 0; face < 5; face++) { |
|
- | 2839 | cube_robj = track->textures[idx].cube_info[face].robj; |
|
- | 2840 | w = track->textures[idx].cube_info[face].width; |
|
- | 2841 | h = track->textures[idx].cube_info[face].height; |
|
- | 2842 | ||
- | 2843 | if (compress_format) { |
|
- | 2844 | size = r100_track_compress_size(compress_format, w, h); |
|
- | 2845 | } else |
|
- | 2846 | size = w * h; |
|
- | 2847 | size *= track->textures[idx].cpp; |
|
- | 2848 | ||
- | 2849 | size += track->textures[idx].cube_info[face].offset; |
|
- | 2850 | ||
- | 2851 | if (size > radeon_bo_size(cube_robj)) { |
|
- | 2852 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", |
|
- | 2853 | size, radeon_bo_size(cube_robj)); |
|
- | 2854 | r100_cs_track_texture_print(&track->textures[idx]); |
|
- | 2855 | return -1; |
|
- | 2856 | } |
|
- | 2857 | } |
|
- | 2858 | return 0; |
|
- | 2859 | } |
|
- | 2860 | ||
- | 2861 | static int r100_cs_track_texture_check(struct radeon_device *rdev, |
|
- | 2862 | struct r100_cs_track *track) |
|
- | 2863 | { |
|
- | 2864 | struct radeon_bo *robj; |
|
- | 2865 | unsigned long size; |
|
- | 2866 | unsigned u, i, w, h, d; |
|
- | 2867 | int ret; |
|
- | 2868 | ||
- | 2869 | for (u = 0; u < track->num_texture; u++) { |
|
- | 2870 | if (!track->textures[u].enabled) |
|
- | 2871 | continue; |
|
- | 2872 | if (track->textures[u].lookup_disable) |
|
- | 2873 | continue; |
|
- | 2874 | robj = track->textures[u].robj; |
|
- | 2875 | if (robj == NULL) { |
|
- | 2876 | DRM_ERROR("No texture bound to unit %u\n", u); |
|
- | 2877 | return -EINVAL; |
|
- | 2878 | } |
|
- | 2879 | size = 0; |
|
- | 2880 | for (i = 0; i <= track->textures[u].num_levels; i++) { |
|
- | 2881 | if (track->textures[u].use_pitch) { |
|
- | 2882 | if (rdev->family < CHIP_R300) |
|
- | 2883 | w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); |
|
- | 2884 | else |
|
- | 2885 | w = track->textures[u].pitch / (1 << i); |
|
- | 2886 | } else { |
|
- | 2887 | w = track->textures[u].width; |
|
- | 2888 | if (rdev->family >= CHIP_RV515) |
|
- | 2889 | w |= track->textures[u].width_11; |
|
- | 2890 | w = w / (1 << i); |
|
- | 2891 | if (track->textures[u].roundup_w) |
|
- | 2892 | w = roundup_pow_of_two(w); |
|
- | 2893 | } |
|
- | 2894 | h = track->textures[u].height; |
|
- | 2895 | if (rdev->family >= CHIP_RV515) |
|
- | 2896 | h |= track->textures[u].height_11; |
|
- | 2897 | h = h / (1 << i); |
|
- | 2898 | if (track->textures[u].roundup_h) |
|
- | 2899 | h = roundup_pow_of_two(h); |
|
- | 2900 | if (track->textures[u].tex_coord_type == 1) { |
|
- | 2901 | d = (1 << track->textures[u].txdepth) / (1 << i); |
|
- | 2902 | if (!d) |
|
- | 2903 | d = 1; |
|
- | 2904 | } else { |
|
- | 2905 | d = 1; |
|
- | 2906 | } |
|
- | 2907 | if (track->textures[u].compress_format) { |
|
- | 2908 | ||
- | 2909 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; |
|
- | 2910 | /* compressed textures are block based */ |
|
- | 2911 | } else |
|
- | 2912 | size += w * h * d; |
|
- | 2913 | } |
|
- | 2914 | size *= track->textures[u].cpp; |
|
- | 2915 | ||
- | 2916 | switch (track->textures[u].tex_coord_type) { |
|
- | 2917 | case 0: |
|
- | 2918 | case 1: |
|
- | 2919 | break; |
|
- | 2920 | case 2: |
|
- | 2921 | if (track->separate_cube) { |
|
- | 2922 | ret = r100_cs_track_cube(rdev, track, u); |
|
- | 2923 | if (ret) |
|
- | 2924 | return ret; |
|
- | 2925 | } else |
|
- | 2926 | size *= 6; |
|
- | 2927 | break; |
|
- | 2928 | default: |
|
- | 2929 | DRM_ERROR("Invalid texture coordinate type %u for unit " |
|
- | 2930 | "%u\n", track->textures[u].tex_coord_type, u); |
|
- | 2931 | return -EINVAL; |
|
- | 2932 | } |
|
- | 2933 | if (size > radeon_bo_size(robj)) { |
|
- | 2934 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " |
|
- | 2935 | "%lu\n", u, size, radeon_bo_size(robj)); |
|
- | 2936 | r100_cs_track_texture_print(&track->textures[u]); |
|
- | 2937 | return -EINVAL; |
|
- | 2938 | } |
|
- | 2939 | } |
|
Line -... | Line 2940... | ||
- | 2940 | return 0; |
|
- | 2941 | } |
|
- | 2942 | ||
- | 2943 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) |
|
- | 2944 | { |
|
- | 2945 | unsigned i; |
|
- | 2946 | unsigned long size; |
|
- | 2947 | unsigned prim_walk; |
|
- | 2948 | unsigned nverts; |
|
- | 2949 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; |
|
- | 2950 | ||
- | 2951 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && |
|
- | 2952 | !track->blend_read_enable) |
|
- | 2953 | num_cb = 0; |
|
- | 2954 | ||
- | 2955 | for (i = 0; i < num_cb; i++) { |
|
- | 2956 | if (track->cb[i].robj == NULL) { |
|
- | 2957 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
|
- | 2958 | return -EINVAL; |
|
- | 2959 | } |
|
- | 2960 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; |
|
- | 2961 | size += track->cb[i].offset; |
|
- | 2962 | if (size > radeon_bo_size(track->cb[i].robj)) { |
|
- | 2963 | DRM_ERROR("[drm] Buffer too small for color buffer %d " |
|
- | 2964 | "(need %lu have %lu) !\n", i, size, |
|
- | 2965 | radeon_bo_size(track->cb[i].robj)); |
|
- | 2966 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", |
|
- | 2967 | i, track->cb[i].pitch, track->cb[i].cpp, |
|
- | 2968 | track->cb[i].offset, track->maxy); |
|
- | 2969 | return -EINVAL; |
|
- | 2970 | } |
|
- | 2971 | } |
|
- | 2972 | track->cb_dirty = false; |
|
- | 2973 | ||
- | 2974 | if (track->zb_dirty && track->z_enabled) { |
|
- | 2975 | if (track->zb.robj == NULL) { |
|
- | 2976 | DRM_ERROR("[drm] No buffer for z buffer !\n"); |
|
- | 2977 | return -EINVAL; |
|
- | 2978 | } |
|
- | 2979 | size = track->zb.pitch * track->zb.cpp * track->maxy; |
|
- | 2980 | size += track->zb.offset; |
|
- | 2981 | if (size > radeon_bo_size(track->zb.robj)) { |
|
- | 2982 | DRM_ERROR("[drm] Buffer too small for z buffer " |
|
- | 2983 | "(need %lu have %lu) !\n", size, |
|
- | 2984 | radeon_bo_size(track->zb.robj)); |
|
- | 2985 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", |
|
- | 2986 | track->zb.pitch, track->zb.cpp, |
|
- | 2987 | track->zb.offset, track->maxy); |
|
- | 2988 | return -EINVAL; |
|
- | 2989 | } |
|
- | 2990 | } |
|
- | 2991 | track->zb_dirty = false; |
|
- | 2992 | ||
- | 2993 | if (track->aa_dirty && track->aaresolve) { |
|
- | 2994 | if (track->aa.robj == NULL) { |
|
- | 2995 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); |
|
- | 2996 | return -EINVAL; |
|
- | 2997 | } |
|
- | 2998 | /* I believe the format comes from colorbuffer0. */ |
|
- | 2999 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; |
|
- | 3000 | size += track->aa.offset; |
|
- | 3001 | if (size > radeon_bo_size(track->aa.robj)) { |
|
- | 3002 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " |
|
- | 3003 | "(need %lu have %lu) !\n", i, size, |
|
- | 3004 | radeon_bo_size(track->aa.robj)); |
|
- | 3005 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", |
|
- | 3006 | i, track->aa.pitch, track->cb[0].cpp, |
|
- | 3007 | track->aa.offset, track->maxy); |
|
- | 3008 | return -EINVAL; |
|
- | 3009 | } |
|
- | 3010 | } |
|
- | 3011 | track->aa_dirty = false; |
|
- | 3012 | ||
- | 3013 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
|
- | 3014 | if (track->vap_vf_cntl & (1 << 14)) { |
|
- | 3015 | nverts = track->vap_alt_nverts; |
|
- | 3016 | } else { |
|
- | 3017 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; |
|
- | 3018 | } |
|
- | 3019 | switch (prim_walk) { |
|
- | 3020 | case 1: |
|
- | 3021 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 3022 | size = track->arrays[i].esize * track->max_indx * 4; |
|
- | 3023 | if (track->arrays[i].robj == NULL) { |
|
- | 3024 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
|
- | 3025 | "bound\n", prim_walk, i); |
|
- | 3026 | return -EINVAL; |
|
- | 3027 | } |
|
- | 3028 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
|
- | 3029 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
|
- | 3030 | "need %lu dwords have %lu dwords\n", |
|
- | 3031 | prim_walk, i, size >> 2, |
|
- | 3032 | radeon_bo_size(track->arrays[i].robj) |
|
- | 3033 | >> 2); |
|
- | 3034 | DRM_ERROR("Max indices %u\n", track->max_indx); |
|
- | 3035 | return -EINVAL; |
|
- | 3036 | } |
|
- | 3037 | } |
|
- | 3038 | break; |
|
- | 3039 | case 2: |
|
- | 3040 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 3041 | size = track->arrays[i].esize * (nverts - 1) * 4; |
|
- | 3042 | if (track->arrays[i].robj == NULL) { |
|
- | 3043 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
|
- | 3044 | "bound\n", prim_walk, i); |
|
- | 3045 | return -EINVAL; |
|
- | 3046 | } |
|
- | 3047 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
|
- | 3048 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
|
- | 3049 | "need %lu dwords have %lu dwords\n", |
|
- | 3050 | prim_walk, i, size >> 2, |
|
- | 3051 | radeon_bo_size(track->arrays[i].robj) |
|
- | 3052 | >> 2); |
|
- | 3053 | return -EINVAL; |
|
- | 3054 | } |
|
- | 3055 | } |
|
- | 3056 | break; |
|
- | 3057 | case 3: |
|
- | 3058 | size = track->vtx_size * nverts; |
|
- | 3059 | if (size != track->immd_dwords) { |
|
- | 3060 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", |
|
- | 3061 | track->immd_dwords, size); |
|
- | 3062 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", |
|
- | 3063 | nverts, track->vtx_size); |
|
- | 3064 | return -EINVAL; |
|
- | 3065 | } |
|
- | 3066 | break; |
|
- | 3067 | default: |
|
- | 3068 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", |
|
- | 3069 | prim_walk); |
|
- | 3070 | return -EINVAL; |
|
- | 3071 | } |
|
- | 3072 | ||
- | 3073 | if (track->tex_dirty) { |
|
- | 3074 | track->tex_dirty = false; |
|
- | 3075 | return r100_cs_track_texture_check(rdev, track); |
|
- | 3076 | } |
|
- | 3077 | return 0; |
|
- | 3078 | } |
|
- | 3079 | ||
- | 3080 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) |
|
- | 3081 | { |
|
- | 3082 | unsigned i, face; |
|
- | 3083 | ||
- | 3084 | track->cb_dirty = true; |
|
- | 3085 | track->zb_dirty = true; |
|
- | 3086 | track->tex_dirty = true; |
|
- | 3087 | track->aa_dirty = true; |
|
- | 3088 | ||
- | 3089 | if (rdev->family < CHIP_R300) { |
|
- | 3090 | track->num_cb = 1; |
|
- | 3091 | if (rdev->family <= CHIP_RS200) |
|
- | 3092 | track->num_texture = 3; |
|
- | 3093 | else |
|
- | 3094 | track->num_texture = 6; |
|
- | 3095 | track->maxy = 2048; |
|
- | 3096 | track->separate_cube = 1; |
|
- | 3097 | } else { |
|
- | 3098 | track->num_cb = 4; |
|
- | 3099 | track->num_texture = 16; |
|
- | 3100 | track->maxy = 4096; |
|
- | 3101 | track->separate_cube = 0; |
|
- | 3102 | track->aaresolve = false; |
|
- | 3103 | track->aa.robj = NULL; |
|
- | 3104 | } |
|
- | 3105 | ||
- | 3106 | for (i = 0; i < track->num_cb; i++) { |
|
- | 3107 | track->cb[i].robj = NULL; |
|
- | 3108 | track->cb[i].pitch = 8192; |
|
- | 3109 | track->cb[i].cpp = 16; |
|
- | 3110 | track->cb[i].offset = 0; |
|
- | 3111 | } |
|
- | 3112 | track->z_enabled = true; |
|
- | 3113 | track->zb.robj = NULL; |
|
- | 3114 | track->zb.pitch = 8192; |
|
- | 3115 | track->zb.cpp = 4; |
|
- | 3116 | track->zb.offset = 0; |
|
- | 3117 | track->vtx_size = 0x7F; |
|
- | 3118 | track->immd_dwords = 0xFFFFFFFFUL; |
|
- | 3119 | track->num_arrays = 11; |
|
- | 3120 | track->max_indx = 0x00FFFFFFUL; |
|
- | 3121 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 3122 | track->arrays[i].robj = NULL; |
|
- | 3123 | track->arrays[i].esize = 0x7F; |
|
- | 3124 | } |
|
- | 3125 | for (i = 0; i < track->num_texture; i++) { |
|
- | 3126 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
|
- | 3127 | track->textures[i].pitch = 16536; |
|
- | 3128 | track->textures[i].width = 16536; |
|
- | 3129 | track->textures[i].height = 16536; |
|
- | 3130 | track->textures[i].width_11 = 1 << 11; |
|
- | 3131 | track->textures[i].height_11 = 1 << 11; |
|
- | 3132 | track->textures[i].num_levels = 12; |
|
- | 3133 | if (rdev->family <= CHIP_RS200) { |
|
- | 3134 | track->textures[i].tex_coord_type = 0; |
|
- | 3135 | track->textures[i].txdepth = 0; |
|
- | 3136 | } else { |
|
- | 3137 | track->textures[i].txdepth = 16; |
|
- | 3138 | track->textures[i].tex_coord_type = 1; |
|
- | 3139 | } |
|
- | 3140 | track->textures[i].cpp = 64; |
|
- | 3141 | track->textures[i].robj = NULL; |
|
- | 3142 | /* CS IB emission code makes sure texture unit are disabled */ |
|
- | 3143 | track->textures[i].enabled = false; |
|
- | 3144 | track->textures[i].lookup_disable = false; |
|
- | 3145 | track->textures[i].roundup_w = true; |
|
- | 3146 | track->textures[i].roundup_h = true; |
|
- | 3147 | if (track->separate_cube) |
|
- | 3148 | for (face = 0; face < 5; face++) { |
|
- | 3149 | track->textures[i].cube_info[face].robj = NULL; |
|
- | 3150 | track->textures[i].cube_info[face].width = 16536; |
|
- | 3151 | track->textures[i].cube_info[face].height = 16536; |
|
- | 3152 | track->textures[i].cube_info[face].offset = 0; |
|
- | 3153 | } |
|
Line 2725... | Line 3154... | ||
2725 | } |
3154 | } |
2726 | 3155 | } |
|
2727 | 3156 | #endif |
|
2728 | 3157 | ||
Line 2756... | Line 3185... | ||
2756 | DRM_UDELAY(1); |
3185 | DRM_UDELAY(1); |
2757 | } |
3186 | } |
2758 | if (i < rdev->usec_timeout) { |
3187 | if (i < rdev->usec_timeout) { |
2759 | DRM_INFO("ring test succeeded in %d usecs\n", i); |
3188 | DRM_INFO("ring test succeeded in %d usecs\n", i); |
2760 | } else { |
3189 | } else { |
2761 | DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n", |
3190 | DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n", |
2762 | scratch, tmp); |
3191 | scratch, tmp); |
2763 | r = -EINVAL; |
3192 | r = -EINVAL; |
2764 | } |
3193 | } |
2765 | radeon_scratch_free(rdev, scratch); |
3194 | radeon_scratch_free(rdev, scratch); |
2766 | return r; |
3195 | return r; |
2767 | } |
3196 | } |
Line -... | Line 3197... | ||
- | 3197 | ||
- | 3198 | #if 0 |
|
- | 3199 | ||
- | 3200 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
|
- | 3201 | { |
|
- | 3202 | radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); |
|
- | 3203 | radeon_ring_write(rdev, ib->gpu_addr); |
|
- | 3204 | radeon_ring_write(rdev, ib->length_dw); |
|
- | 3205 | } |
|
- | 3206 | ||
- | 3207 | int r100_ib_test(struct radeon_device *rdev) |
|
- | 3208 | { |
|
- | 3209 | struct radeon_ib *ib; |
|
- | 3210 | uint32_t scratch; |
|
- | 3211 | uint32_t tmp = 0; |
|
- | 3212 | unsigned i; |
|
- | 3213 | int r; |
|
- | 3214 | ||
- | 3215 | r = radeon_scratch_get(rdev, &scratch); |
|
- | 3216 | if (r) { |
|
- | 3217 | DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); |
|
- | 3218 | return r; |
|
- | 3219 | } |
|
- | 3220 | WREG32(scratch, 0xCAFEDEAD); |
|
- | 3221 | r = radeon_ib_get(rdev, &ib); |
|
- | 3222 | if (r) { |
|
- | 3223 | return r; |
|
- | 3224 | } |
|
- | 3225 | ib->ptr[0] = PACKET0(scratch, 0); |
|
- | 3226 | ib->ptr[1] = 0xDEADBEEF; |
|
- | 3227 | ib->ptr[2] = PACKET2(0); |
|
- | 3228 | ib->ptr[3] = PACKET2(0); |
|
- | 3229 | ib->ptr[4] = PACKET2(0); |
|
- | 3230 | ib->ptr[5] = PACKET2(0); |
|
- | 3231 | ib->ptr[6] = PACKET2(0); |
|
- | 3232 | ib->ptr[7] = PACKET2(0); |
|
- | 3233 | ib->length_dw = 8; |
|
- | 3234 | r = radeon_ib_schedule(rdev, ib); |
|
- | 3235 | if (r) { |
|
- | 3236 | radeon_scratch_free(rdev, scratch); |
|
- | 3237 | radeon_ib_free(rdev, &ib); |
|
- | 3238 | return r; |
|
- | 3239 | } |
|
- | 3240 | r = radeon_fence_wait(ib->fence, false); |
|
- | 3241 | if (r) { |
|
- | 3242 | return r; |
|
- | 3243 | } |
|
- | 3244 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 3245 | tmp = RREG32(scratch); |
|
- | 3246 | if (tmp == 0xDEADBEEF) { |
|
- | 3247 | break; |
|
- | 3248 | } |
|
- | 3249 | DRM_UDELAY(1); |
|
- | 3250 | } |
|
- | 3251 | if (i < rdev->usec_timeout) { |
|
- | 3252 | DRM_INFO("ib test succeeded in %u usecs\n", i); |
|
- | 3253 | } else { |
|
- | 3254 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
|
- | 3255 | scratch, tmp); |
|
- | 3256 | r = -EINVAL; |
|
- | 3257 | } |
|
- | 3258 | radeon_scratch_free(rdev, scratch); |
|
- | 3259 | radeon_ib_free(rdev, &ib); |
|
- | 3260 | return r; |
|
- | 3261 | } |
|
- | 3262 | ||
- | 3263 | void r100_ib_fini(struct radeon_device *rdev) |
|
- | 3264 | { |
|
- | 3265 | radeon_ib_pool_fini(rdev); |
|
- | 3266 | } |
|
- | 3267 | ||
- | 3268 | int r100_ib_init(struct radeon_device *rdev) |
|
- | 3269 | { |
|
- | 3270 | int r; |
|
- | 3271 | ||
- | 3272 | r = radeon_ib_pool_init(rdev); |
|
- | 3273 | if (r) { |
|
- | 3274 | dev_err(rdev->dev, "failed initializing IB pool (%d).\n", r); |
|
- | 3275 | r100_ib_fini(rdev); |
|
- | 3276 | return r; |
|
- | 3277 | } |
|
- | 3278 | r = r100_ib_test(rdev); |
|
- | 3279 | if (r) { |
|
- | 3280 | dev_err(rdev->dev, "failed testing IB (%d).\n", r); |
|
- | 3281 | r100_ib_fini(rdev); |
|
- | 3282 | return r; |
|
- | 3283 | } |
|
- | 3284 | return 0; |
|
- | 3285 | } |
|
- | 3286 | #endif |
|
2768 | 3287 | ||
2769 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
3288 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
2770 | { |
3289 | { |
2771 | /* Shutdown CP we shouldn't need to do that but better be safe than |
3290 | /* Shutdown CP we shouldn't need to do that but better be safe than |
2772 | * sorry |
3291 | * sorry |
Line 2907... | Line 3426... | ||
2907 | r100_set_common_regs(rdev); |
3426 | r100_set_common_regs(rdev); |
2908 | /* program mc */ |
3427 | /* program mc */ |
2909 | r100_mc_program(rdev); |
3428 | r100_mc_program(rdev); |
2910 | /* Resume clock */ |
3429 | /* Resume clock */ |
2911 | r100_clock_startup(rdev); |
3430 | r100_clock_startup(rdev); |
2912 | /* Initialize GPU configuration (# pipes, ...) */ |
- | |
2913 | r100_gpu_init(rdev); |
- | |
2914 | /* Initialize GART (initialize after TTM so we can allocate |
3431 | /* Initialize GART (initialize after TTM so we can allocate |
2915 | * memory through TTM but finalize after TTM) */ |
3432 | * memory through TTM but finalize after TTM) */ |
2916 | r100_enable_bm(rdev); |
3433 | r100_enable_bm(rdev); |
2917 | if (rdev->flags & RADEON_IS_PCI) { |
3434 | if (rdev->flags & RADEON_IS_PCI) { |
2918 | r = r100_pci_gart_enable(rdev); |
3435 | r = r100_pci_gart_enable(rdev); |
Line 2923... | Line 3440... | ||
2923 | // r100_irq_set(rdev); |
3440 | // r100_irq_set(rdev); |
2924 | rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
3441 | rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
2925 | /* 1M ring buffer */ |
3442 | /* 1M ring buffer */ |
2926 | r = r100_cp_init(rdev, 1024 * 1024); |
3443 | r = r100_cp_init(rdev, 1024 * 1024); |
2927 | if (r) { |
3444 | if (r) { |
2928 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); |
3445 | dev_err(rdev->dev, "failed initializing CP (%d).\n", r); |
2929 | return r; |
3446 | return r; |
2930 | } |
3447 | } |
2931 | // r = r100_wb_init(rdev); |
- | |
2932 | // if (r) |
- | |
2933 | // dev_err(rdev->dev, "failled initializing WB (%d).\n", r); |
- | |
2934 | // r = r100_ib_init(rdev); |
3448 | // r = r100_ib_init(rdev); |
2935 | // if (r) { |
3449 | // if (r) { |
2936 | // dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
3450 | // dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
2937 | // return r; |
3451 | // return r; |
2938 | // } |
3452 | // } |
2939 | return 0; |
3453 | return 0; |
2940 | } |
3454 | } |
Line -... | Line 3455... | ||
- | 3455 | ||
- | 3456 | /* |
|
- | 3457 | * Due to how kexec works, it can leave the hw fully initialised when it |
|
- | 3458 | * boots the new kernel. However doing our init sequence with the CP and |
|
- | 3459 | * WB stuff setup causes GPU hangs on the RN50 at least. So at startup |
|
- | 3460 | * do some quick sanity checks and restore sane values to avoid this |
|
- | 3461 | * problem. |
|
- | 3462 | */ |
|
- | 3463 | void r100_restore_sanity(struct radeon_device *rdev) |
|
- | 3464 | { |
|
Line -... | Line 3465... | ||
- | 3465 | u32 tmp; |
|
- | 3466 | ||
- | 3467 | tmp = RREG32(RADEON_CP_CSQ_CNTL); |
|
- | 3468 | if (tmp) { |
|
- | 3469 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
|
- | 3470 | } |
|
- | 3471 | tmp = RREG32(RADEON_CP_RB_CNTL); |
|
- | 3472 | if (tmp) { |
|
- | 3473 | WREG32(RADEON_CP_RB_CNTL, 0); |
|
- | 3474 | } |
|
- | 3475 | tmp = RREG32(RADEON_SCRATCH_UMSK); |
|
- | 3476 | if (tmp) { |
|
- | 3477 | WREG32(RADEON_SCRATCH_UMSK, 0); |
|
Line 2941... | Line 3478... | ||
2941 | 3478 | } |
|
2942 | 3479 | } |
|
2943 | 3480 | ||
Line 2951... | Line 3488... | ||
2951 | r100_vga_render_disable(rdev); |
3488 | r100_vga_render_disable(rdev); |
2952 | /* Initialize scratch registers */ |
3489 | /* Initialize scratch registers */ |
2953 | radeon_scratch_init(rdev); |
3490 | radeon_scratch_init(rdev); |
2954 | /* Initialize surface registers */ |
3491 | /* Initialize surface registers */ |
2955 | radeon_surface_init(rdev); |
3492 | radeon_surface_init(rdev); |
- | 3493 | /* sanity check some register to avoid hangs like after kexec */ |
|
- | 3494 | r100_restore_sanity(rdev); |
|
2956 | /* TODO: disable VGA need to use VGA request */ |
3495 | /* TODO: disable VGA need to use VGA request */ |
2957 | /* BIOS*/ |
3496 | /* BIOS*/ |
2958 | if (!radeon_get_bios(rdev)) { |
3497 | if (!radeon_get_bios(rdev)) { |
2959 | if (ASIC_IS_AVIVO(rdev)) |
3498 | if (ASIC_IS_AVIVO(rdev)) |
2960 | return -EINVAL; |
3499 | return -EINVAL; |
Line 2966... | Line 3505... | ||
2966 | r = radeon_combios_init(rdev); |
3505 | r = radeon_combios_init(rdev); |
2967 | if (r) |
3506 | if (r) |
2968 | return r; |
3507 | return r; |
2969 | } |
3508 | } |
2970 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
3509 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
2971 | if (radeon_gpu_reset(rdev)) { |
3510 | if (radeon_asic_reset(rdev)) { |
2972 | dev_warn(rdev->dev, |
3511 | dev_warn(rdev->dev, |
2973 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
3512 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
2974 | RREG32(R_000E40_RBBM_STATUS), |
3513 | RREG32(R_000E40_RBBM_STATUS), |
2975 | RREG32(R_0007C0_CP_STAT)); |
3514 | RREG32(R_0007C0_CP_STAT)); |
2976 | } |
3515 | } |
Line 2979... | Line 3518... | ||
2979 | return -EINVAL; |
3518 | return -EINVAL; |
2980 | /* Set asic errata */ |
3519 | /* Set asic errata */ |
2981 | r100_errata(rdev); |
3520 | r100_errata(rdev); |
2982 | /* Initialize clocks */ |
3521 | /* Initialize clocks */ |
2983 | radeon_get_clock_info(rdev->ddev); |
3522 | radeon_get_clock_info(rdev->ddev); |
2984 | /* Initialize power management */ |
- | |
2985 | radeon_pm_init(rdev); |
- | |
2986 | /* initialize AGP */ |
3523 | /* initialize AGP */ |
2987 | if (rdev->flags & RADEON_IS_AGP) { |
3524 | if (rdev->flags & RADEON_IS_AGP) { |
2988 | r = radeon_agp_init(rdev); |
3525 | r = radeon_agp_init(rdev); |
2989 | if (r) { |
3526 | if (r) { |
2990 | radeon_agp_disable(rdev); |
3527 | radeon_agp_disable(rdev); |
Line 3017... | Line 3554... | ||
3017 | // r100_cp_fini(rdev); |
3554 | // r100_cp_fini(rdev); |
3018 | // r100_wb_fini(rdev); |
3555 | // r100_wb_fini(rdev); |
3019 | // r100_ib_fini(rdev); |
3556 | // r100_ib_fini(rdev); |
3020 | if (rdev->flags & RADEON_IS_PCI) |
3557 | if (rdev->flags & RADEON_IS_PCI) |
3021 | r100_pci_gart_fini(rdev); |
3558 | r100_pci_gart_fini(rdev); |
3022 | // radeon_irq_kms_fini(rdev); |
- | |
3023 | rdev->accel_working = false; |
3559 | rdev->accel_working = false; |
3024 | } |
3560 | } |
3025 | return 0; |
3561 | return 0; |
3026 | }>>><>><>><>><>><>>>><>><>><>><>><>><>><>><>><>>=>>>><>=>><>><>><>><>=>=>>><>>><>=>><>>=>>>><>9); |
3562 | }>>>>>=>><>><>>>>=>>>>><>>><>><>><>><>><>><>>=>>>>><>><>><>><>><>>>><>><>><>><>><>><>><>><>><>>=>>>><>=>><>><>><>><>>=>=>><>>><>=>><>>=>>>><>><>=>><>>>>>>>><>><>>><>><>><>><>><>>><>><>=>><>=>><>><>><>>>><>><>><>><>><>><>> |