Rev 1129 | Rev 1221 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1129 | Rev 1179 | ||
---|---|---|---|
Line 23... | Line 23... | ||
23 | * |
23 | * |
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 "drmP.h" |
29 | #include "drmP.h" |
30 | #include "drm.h" |
30 | #include "drm.h" |
31 | #include "radeon_drm.h" |
31 | #include "radeon_drm.h" |
32 | #include "radeon_microcode.h" |
32 | #include "radeon_microcode.h" |
33 | #include "radeon_reg.h" |
33 | #include "radeon_reg.h" |
34 | #include "radeon.h" |
34 | #include "radeon.h" |
- | 35 | #include "r100d.h" |
|
Line -... | Line 36... | ||
- | 36 | ||
- | 37 | #include "r100_reg_safe.h" |
|
35 | 38 | #include "rn50_reg_safe.h" |
|
36 | /* This files gather functions specifics to: |
39 | /* This files gather functions specifics to: |
37 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
40 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
38 | * |
41 | * |
39 | * Some of these functions might be used by newer ASICs. |
42 | * Some of these functions might be used by newer ASICs. |
- | 43 | */ |
|
40 | */ |
44 | int r200_init(struct radeon_device *rdev); |
41 | void r100_hdp_reset(struct radeon_device *rdev); |
45 | void r100_hdp_reset(struct radeon_device *rdev); |
42 | void r100_gpu_init(struct radeon_device *rdev); |
46 | void r100_gpu_init(struct radeon_device *rdev); |
43 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
47 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
44 | int r100_mc_wait_for_idle(struct radeon_device *rdev); |
48 | int r100_mc_wait_for_idle(struct radeon_device *rdev); |
45 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev); |
49 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev); |
46 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev); |
50 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev); |
Line -... | Line 51... | ||
- | 51 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
|
47 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
52 | |
48 | 53 | ||
49 | /* |
54 | /* |
50 | * PCI GART |
55 | * PCI GART |
51 | */ |
56 | */ |
Line 55... | Line 60... | ||
55 | /* It seems hw only cache one entry so we should discard this |
60 | /* It seems hw only cache one entry so we should discard this |
56 | * entry otherwise if first GPU GART read hit this entry it |
61 | * entry otherwise if first GPU GART read hit this entry it |
57 | * could end up in wrong address. */ |
62 | * could end up in wrong address. */ |
58 | } |
63 | } |
Line 59... | Line 64... | ||
59 | 64 | ||
60 | int r100_pci_gart_enable(struct radeon_device *rdev) |
65 | int r100_pci_gart_init(struct radeon_device *rdev) |
61 | { |
- | |
62 | uint32_t tmp; |
66 | { |
Line -... | Line 67... | ||
- | 67 | int r; |
|
- | 68 | ||
- | 69 | if (rdev->gart.table.ram.ptr) { |
|
- | 70 | WARN(1, "R100 PCI GART already initialized.\n"); |
|
63 | int r; |
71 | return 0; |
64 | 72 | } |
|
65 | /* Initialize common gart structure */ |
73 | /* Initialize common gart structure */ |
66 | r = radeon_gart_init(rdev); |
74 | r = radeon_gart_init(rdev); |
67 | if (r) { |
- | |
68 | return r; |
- | |
69 | } |
75 | if (r) |
- | 76 | return r; |
|
- | 77 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
|
70 | if (rdev->gart.table.ram.ptr == NULL) { |
78 | rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; |
71 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
- | |
72 | r = radeon_gart_table_ram_alloc(rdev); |
- | |
73 | if (r) { |
- | |
74 | return r; |
79 | rdev->asic->gart_set_page = &r100_pci_gart_set_page; |
- | 80 | return radeon_gart_table_ram_alloc(rdev); |
|
- | 81 | } |
|
- | 82 | ||
- | 83 | int r100_pci_gart_enable(struct radeon_device *rdev) |
|
- | 84 | { |
|
75 | } |
85 | uint32_t tmp; |
76 | } |
86 | |
77 | /* discard memory request outside of configured range */ |
87 | /* discard memory request outside of configured range */ |
78 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; |
88 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_DIS_OUT_OF_PCI_GART_ACCESS; |
79 | WREG32(RADEON_AIC_CNTL, tmp); |
89 | WREG32(RADEON_AIC_CNTL, tmp); |
Line 102... | Line 112... | ||
102 | WREG32(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN); |
112 | WREG32(RADEON_AIC_CNTL, tmp & ~RADEON_PCIGART_TRANSLATE_EN); |
103 | WREG32(RADEON_AIC_LO_ADDR, 0); |
113 | WREG32(RADEON_AIC_LO_ADDR, 0); |
104 | WREG32(RADEON_AIC_HI_ADDR, 0); |
114 | WREG32(RADEON_AIC_HI_ADDR, 0); |
105 | } |
115 | } |
Line 106... | Line -... | ||
106 | - | ||
107 | 116 | ||
108 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
117 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
109 | { |
118 | { |
110 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
119 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
111 | return -EINVAL; |
120 | return -EINVAL; |
112 | } |
121 | } |
113 | rdev->gart.table.ram.ptr[i] = cpu_to_le32((uint32_t)addr); |
122 | rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr)); |
114 | return 0; |
123 | return 0; |
Line 115... | Line 124... | ||
115 | } |
124 | } |
116 | 125 | ||
117 | int r100_gart_enable(struct radeon_device *rdev) |
- | |
118 | { |
126 | void r100_pci_gart_fini(struct radeon_device *rdev) |
119 | if (rdev->flags & RADEON_IS_AGP) { |
127 | { |
120 | r100_pci_gart_disable(rdev); |
- | |
121 | return 0; |
128 | r100_pci_gart_disable(rdev); |
122 | } |
129 | radeon_gart_table_ram_free(rdev); |
Line 123... | Line 130... | ||
123 | return r100_pci_gart_enable(rdev); |
130 | radeon_gart_fini(rdev); |
124 | } |
131 | } |
Line 171... | Line 178... | ||
171 | r = r100_debugfs_mc_info_init(rdev); |
178 | r = r100_debugfs_mc_info_init(rdev); |
172 | if (r) { |
179 | if (r) { |
173 | DRM_ERROR("Failed to register debugfs file for R100 MC !\n"); |
180 | DRM_ERROR("Failed to register debugfs file for R100 MC !\n"); |
174 | } |
181 | } |
175 | /* Write VRAM size in case we are limiting it */ |
182 | /* Write VRAM size in case we are limiting it */ |
176 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size); |
183 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
- | 184 | /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM, |
|
- | 185 | * if the aperture is 64MB but we have 32MB VRAM |
|
- | 186 | * we report only 32MB VRAM but we have to set MC_FB_LOCATION |
|
- | 187 | * to 64MB, otherwise the gpu accidentially dies */ |
|
177 | tmp = rdev->mc.vram_location + rdev->mc.vram_size - 1; |
188 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
178 | tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16); |
189 | tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16); |
179 | tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16); |
190 | tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16); |
180 | WREG32(RADEON_MC_FB_LOCATION, tmp); |
191 | WREG32(RADEON_MC_FB_LOCATION, tmp); |
Line 181... | Line 192... | ||
181 | 192 | ||
Line 213... | Line 224... | ||
213 | r100_gpu_init(rdev); |
224 | r100_gpu_init(rdev); |
214 | /* Disable gart which also disable out of gart access */ |
225 | /* Disable gart which also disable out of gart access */ |
215 | r100_pci_gart_disable(rdev); |
226 | r100_pci_gart_disable(rdev); |
Line 216... | Line 227... | ||
216 | 227 | ||
217 | /* Setup GPU memory space */ |
- | |
218 | rdev->mc.vram_location = 0xFFFFFFFFUL; |
228 | /* Setup GPU memory space */ |
219 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
- | |
220 | if (rdev->flags & RADEON_IS_AGP) { |
- | |
221 | r = radeon_agp_init(rdev); |
- | |
222 | if (r) { |
- | |
223 | printk(KERN_WARNING "[drm] Disabling AGP\n"); |
- | |
224 | rdev->flags &= ~RADEON_IS_AGP; |
- | |
225 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
- | |
226 | } else { |
- | |
227 | rdev->mc.gtt_location = rdev->mc.agp_base; |
- | |
228 | } |
- | |
229 | } |
229 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
230 | r = radeon_mc_setup(rdev); |
230 | r = radeon_mc_setup(rdev); |
231 | if (r) { |
231 | if (r) { |
232 | return r; |
232 | return r; |
Line 242... | Line 242... | ||
242 | return 0; |
242 | return 0; |
243 | } |
243 | } |
Line 244... | Line 244... | ||
244 | 244 | ||
245 | void r100_mc_fini(struct radeon_device *rdev) |
245 | void r100_mc_fini(struct radeon_device *rdev) |
246 | { |
- | |
247 | r100_pci_gart_disable(rdev); |
- | |
248 | // radeon_gart_table_ram_free(rdev); |
- | |
249 | // radeon_gart_fini(rdev); |
246 | { |
Line -... | Line 247... | ||
- | 247 | } |
|
- | 248 | ||
- | 249 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) |
|
- | 250 | { |
|
- | 251 | if (crtc == 0) |
|
- | 252 | return RREG32(RADEON_CRTC_CRNT_FRAME); |
|
- | 253 | else |
|
- | 254 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
|
- | 255 | } |
|
250 | } |
256 | |
251 | 257 | ||
252 | /* |
258 | /* |
253 | * Fence emission |
259 | * Fence emission |
254 | */ |
260 | */ |
Line 295... | Line 301... | ||
295 | if (r) { |
301 | if (r) { |
296 | DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); |
302 | DRM_ERROR("radeon: failed to map WB buffer (%d).\n", r); |
297 | return r; |
303 | return r; |
298 | } |
304 | } |
299 | } |
305 | } |
300 | WREG32(0x774, rdev->wb.gpu_addr); |
306 | WREG32(R_000774_SCRATCH_ADDR, rdev->wb.gpu_addr); |
- | 307 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
|
301 | WREG32(0x70C, rdev->wb.gpu_addr + 1024); |
308 | S_00070C_RB_RPTR_ADDR((rdev->wb.gpu_addr + 1024) >> 2)); |
302 | WREG32(0x770, 0xff); |
309 | WREG32(R_000770_SCRATCH_UMSK, 0xff); |
303 | return 0; |
310 | return 0; |
304 | } |
311 | } |
Line -... | Line 312... | ||
- | 312 | ||
- | 313 | void r100_wb_disable(struct radeon_device *rdev) |
|
- | 314 | { |
|
- | 315 | WREG32(R_000770_SCRATCH_UMSK, 0); |
|
- | 316 | } |
|
305 | 317 | ||
306 | void r100_wb_fini(struct radeon_device *rdev) |
318 | void r100_wb_fini(struct radeon_device *rdev) |
- | 319 | { |
|
307 | { |
320 | r100_wb_disable(rdev); |
308 | if (rdev->wb.wb_obj) { |
321 | if (rdev->wb.wb_obj) { |
309 | // radeon_object_kunmap(rdev->wb.wb_obj); |
322 | // radeon_object_kunmap(rdev->wb.wb_obj); |
310 | // radeon_object_unpin(rdev->wb.wb_obj); |
323 | // radeon_object_unpin(rdev->wb.wb_obj); |
311 | // radeon_object_unref(&rdev->wb.wb_obj); |
324 | // radeon_object_unref(&rdev->wb.wb_obj); |
312 | rdev->wb.wb = NULL; |
325 | rdev->wb.wb = NULL; |
313 | rdev->wb.wb_obj = NULL; |
326 | rdev->wb.wb_obj = NULL; |
314 | } |
327 | } |
Line 315... | Line -... | ||
315 | } |
- | |
316 | 328 | } |
|
317 | 329 | ||
318 | int r100_copy_blit(struct radeon_device *rdev, |
330 | int r100_copy_blit(struct radeon_device *rdev, |
319 | uint64_t src_offset, |
331 | uint64_t src_offset, |
320 | uint64_t dst_offset, |
332 | uint64_t dst_offset, |
Line 391... | Line 403... | ||
391 | #endif |
403 | #endif |
Line 392... | Line 404... | ||
392 | 404 | ||
393 | /* |
405 | /* |
394 | * CP |
406 | * CP |
- | 407 | */ |
|
- | 408 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
|
- | 409 | { |
|
- | 410 | unsigned i; |
|
- | 411 | u32 tmp; |
|
- | 412 | ||
- | 413 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 414 | tmp = RREG32(R_000E40_RBBM_STATUS); |
|
- | 415 | if (!G_000E40_CP_CMDSTRM_BUSY(tmp)) { |
|
- | 416 | return 0; |
|
- | 417 | } |
|
- | 418 | udelay(1); |
|
- | 419 | } |
|
- | 420 | return -1; |
|
- | 421 | } |
|
395 | */ |
422 | |
396 | void r100_ring_start(struct radeon_device *rdev) |
423 | void r100_ring_start(struct radeon_device *rdev) |
397 | { |
424 | { |
Line 398... | Line 425... | ||
398 | int r; |
425 | int r; |
Line 481... | Line 508... | ||
481 | WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); |
508 | WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); |
482 | } |
509 | } |
483 | } |
510 | } |
484 | } |
511 | } |
Line -... | Line 512... | ||
- | 512 | ||
- | 513 | static int r100_cp_init_microcode(struct radeon_device *rdev) |
|
- | 514 | { |
|
- | 515 | return 0; |
|
- | 516 | } |
|
- | 517 | ||
485 | 518 | ||
486 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) |
519 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) |
487 | { |
520 | { |
488 | unsigned rb_bufsz; |
521 | unsigned rb_bufsz; |
489 | unsigned rb_blksz; |
522 | unsigned rb_blksz; |
Line 515... | Line 548... | ||
515 | DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp); |
548 | DRM_INFO("radeon: cp reset failed (0x%08X)\n", tmp); |
516 | } |
549 | } |
517 | } else { |
550 | } else { |
518 | DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); |
551 | DRM_INFO("radeon: cp idle (0x%08X)\n", tmp); |
519 | } |
552 | } |
- | 553 | ||
- | 554 | if (!rdev->me_fw) { |
|
- | 555 | r = r100_cp_init_microcode(rdev); |
|
- | 556 | if (r) { |
|
- | 557 | DRM_ERROR("Failed to load firmware!\n"); |
|
- | 558 | return r; |
|
- | 559 | } |
|
- | 560 | } |
|
- | 561 | ||
520 | /* Align ring size */ |
562 | /* Align ring size */ |
521 | rb_bufsz = drm_order(ring_size / 8); |
563 | rb_bufsz = drm_order(ring_size / 8); |
522 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
564 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
523 | r100_cp_load_microcode(rdev); |
565 | r100_cp_load_microcode(rdev); |
524 | r = radeon_ring_init(rdev, ring_size); |
566 | r = radeon_ring_init(rdev, ring_size); |
Line 586... | Line 628... | ||
586 | } |
628 | } |
587 | rdev->cp.ready = true; |
629 | rdev->cp.ready = true; |
588 | return 0; |
630 | return 0; |
589 | } |
631 | } |
Line 590... | Line -... | ||
590 | - | ||
591 | 632 | ||
592 | void r100_cp_fini(struct radeon_device *rdev) |
633 | void r100_cp_fini(struct radeon_device *rdev) |
- | 634 | { |
|
- | 635 | if (r100_cp_wait_for_idle(rdev)) { |
|
- | 636 | DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n"); |
|
593 | { |
637 | } |
594 | /* Disable ring */ |
638 | /* Disable ring */ |
595 | rdev->cp.ready = false; |
- | |
596 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
639 | r100_cp_disable(rdev); |
597 | radeon_ring_fini(rdev); |
640 | radeon_ring_fini(rdev); |
598 | DRM_INFO("radeon: cp finalized\n"); |
641 | DRM_INFO("radeon: cp finalized\n"); |
Line 599... | Line 642... | ||
599 | } |
642 | } |
Line 608... | Line 651... | ||
608 | printk(KERN_WARNING "Failed to wait GUI idle while " |
651 | printk(KERN_WARNING "Failed to wait GUI idle while " |
609 | "programming pipes. Bad things might happen.\n"); |
652 | "programming pipes. Bad things might happen.\n"); |
610 | } |
653 | } |
611 | } |
654 | } |
Line 612... | Line -... | ||
612 | - | ||
613 | 655 | ||
614 | int r100_cp_reset(struct radeon_device *rdev) |
656 | int r100_cp_reset(struct radeon_device *rdev) |
615 | { |
657 | { |
616 | uint32_t tmp; |
658 | uint32_t tmp; |
617 | bool reinit_cp; |
659 | bool reinit_cp; |
Line 618... | Line 660... | ||
618 | int i; |
660 | int i; |
619 | - | ||
Line 620... | Line 661... | ||
620 | dbgprintf("%s\n",__FUNCTION__); |
661 | |
621 | 662 | ENTER(); |
|
622 | 663 | ||
623 | reinit_cp = rdev->cp.ready; |
664 | reinit_cp = rdev->cp.ready; |
Line 645... | Line 686... | ||
645 | tmp = RREG32(RADEON_RBBM_STATUS); |
686 | tmp = RREG32(RADEON_RBBM_STATUS); |
646 | DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp); |
687 | DRM_ERROR("Failed to reset CP (RBBM_STATUS=0x%08X)!\n", tmp); |
647 | return -1; |
688 | return -1; |
648 | } |
689 | } |
Line -... | Line 690... | ||
- | 690 | ||
- | 691 | void r100_cp_commit(struct radeon_device *rdev) |
|
- | 692 | { |
|
- | 693 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); |
|
- | 694 | (void)RREG32(RADEON_CP_RB_WPTR); |
|
- | 695 | } |
|
- | 696 | ||
649 | 697 | ||
650 | #if 0 |
698 | #if 0 |
651 | /* |
699 | /* |
652 | * CS functions |
700 | * CS functions |
653 | */ |
701 | */ |
Line 723... | Line 771... | ||
723 | int r100_cs_packet_parse(struct radeon_cs_parser *p, |
771 | int r100_cs_packet_parse(struct radeon_cs_parser *p, |
724 | struct radeon_cs_packet *pkt, |
772 | struct radeon_cs_packet *pkt, |
725 | unsigned idx) |
773 | unsigned idx) |
726 | { |
774 | { |
727 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; |
775 | struct radeon_cs_chunk *ib_chunk = &p->chunks[p->chunk_ib_idx]; |
728 | uint32_t header = ib_chunk->kdata[idx]; |
776 | uint32_t header; |
Line 729... | Line 777... | ||
729 | 777 | ||
730 | if (idx >= ib_chunk->length_dw) { |
778 | if (idx >= ib_chunk->length_dw) { |
731 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", |
779 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", |
732 | idx, ib_chunk->length_dw); |
780 | idx, ib_chunk->length_dw); |
733 | return -EINVAL; |
781 | return -EINVAL; |
- | 782 | } |
|
734 | } |
783 | header = ib_chunk->kdata[idx]; |
735 | pkt->idx = idx; |
784 | pkt->idx = idx; |
736 | pkt->type = CP_PACKET_GET_TYPE(header); |
785 | pkt->type = CP_PACKET_GET_TYPE(header); |
737 | pkt->count = CP_PACKET_GET_COUNT(header); |
786 | pkt->count = CP_PACKET_GET_COUNT(header); |
738 | switch (pkt->type) { |
787 | switch (pkt->type) { |
Line 757... | Line 806... | ||
757 | } |
806 | } |
758 | return 0; |
807 | return 0; |
759 | } |
808 | } |
Line 760... | Line 809... | ||
760 | 809 | ||
- | 810 | /** |
|
- | 811 | * r100_cs_packet_next_vline() - parse userspace VLINE packet |
|
- | 812 | * @parser: parser structure holding parsing context. |
|
- | 813 | * |
|
- | 814 | * Userspace sends a special sequence for VLINE waits. |
|
- | 815 | * PACKET0 - VLINE_START_END + value |
|
- | 816 | * PACKET0 - WAIT_UNTIL +_value |
|
- | 817 | * RELOC (P3) - crtc_id in reloc. |
|
- | 818 | * |
|
- | 819 | * This function parses this and relocates the VLINE START END |
|
- | 820 | * and WAIT UNTIL packets to the correct crtc. |
|
- | 821 | * It also detects a switched off crtc and nulls out the |
|
- | 822 | * wait in that case. |
|
- | 823 | */ |
|
- | 824 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) |
|
- | 825 | { |
|
- | 826 | struct radeon_cs_chunk *ib_chunk; |
|
- | 827 | struct drm_mode_object *obj; |
|
- | 828 | struct drm_crtc *crtc; |
|
- | 829 | struct radeon_crtc *radeon_crtc; |
|
- | 830 | struct radeon_cs_packet p3reloc, waitreloc; |
|
- | 831 | int crtc_id; |
|
- | 832 | int r; |
|
- | 833 | uint32_t header, h_idx, reg; |
|
- | 834 | ||
- | 835 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
|
- | 836 | ||
- | 837 | /* parse the wait until */ |
|
- | 838 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
|
- | 839 | if (r) |
|
- | 840 | return r; |
|
- | 841 | ||
- | 842 | /* check its a wait until and only 1 count */ |
|
- | 843 | if (waitreloc.reg != RADEON_WAIT_UNTIL || |
|
- | 844 | waitreloc.count != 0) { |
|
- | 845 | DRM_ERROR("vline wait had illegal wait until segment\n"); |
|
- | 846 | r = -EINVAL; |
|
- | 847 | return r; |
|
- | 848 | } |
|
- | 849 | ||
- | 850 | if (ib_chunk->kdata[waitreloc.idx + 1] != RADEON_WAIT_CRTC_VLINE) { |
|
- | 851 | DRM_ERROR("vline wait had illegal wait until\n"); |
|
- | 852 | r = -EINVAL; |
|
- | 853 | return r; |
|
- | 854 | } |
|
- | 855 | ||
- | 856 | /* jump over the NOP */ |
|
- | 857 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); |
|
- | 858 | if (r) |
|
- | 859 | return r; |
|
- | 860 | ||
- | 861 | h_idx = p->idx - 2; |
|
- | 862 | p->idx += waitreloc.count; |
|
- | 863 | p->idx += p3reloc.count; |
|
- | 864 | ||
- | 865 | header = ib_chunk->kdata[h_idx]; |
|
- | 866 | crtc_id = ib_chunk->kdata[h_idx + 5]; |
|
- | 867 | reg = ib_chunk->kdata[h_idx] >> 2; |
|
- | 868 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
|
- | 869 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); |
|
- | 870 | if (!obj) { |
|
- | 871 | DRM_ERROR("cannot find crtc %d\n", crtc_id); |
|
- | 872 | r = -EINVAL; |
|
- | 873 | goto out; |
|
- | 874 | } |
|
- | 875 | crtc = obj_to_crtc(obj); |
|
- | 876 | radeon_crtc = to_radeon_crtc(crtc); |
|
- | 877 | crtc_id = radeon_crtc->crtc_id; |
|
- | 878 | ||
- | 879 | if (!crtc->enabled) { |
|
- | 880 | /* if the CRTC isn't enabled - we need to nop out the wait until */ |
|
- | 881 | ib_chunk->kdata[h_idx + 2] = PACKET2(0); |
|
- | 882 | ib_chunk->kdata[h_idx + 3] = PACKET2(0); |
|
- | 883 | } else if (crtc_id == 1) { |
|
- | 884 | switch (reg) { |
|
- | 885 | case AVIVO_D1MODE_VLINE_START_END: |
|
- | 886 | header &= R300_CP_PACKET0_REG_MASK; |
|
- | 887 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; |
|
- | 888 | break; |
|
- | 889 | case RADEON_CRTC_GUI_TRIG_VLINE: |
|
- | 890 | header &= R300_CP_PACKET0_REG_MASK; |
|
- | 891 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
|
- | 892 | break; |
|
- | 893 | default: |
|
- | 894 | DRM_ERROR("unknown crtc reloc\n"); |
|
- | 895 | r = -EINVAL; |
|
- | 896 | goto out; |
|
- | 897 | } |
|
- | 898 | ib_chunk->kdata[h_idx] = header; |
|
- | 899 | ib_chunk->kdata[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
|
- | 900 | } |
|
- | 901 | out: |
|
- | 902 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); |
|
- | 903 | return r; |
|
- | 904 | } |
|
- | 905 | ||
761 | /** |
906 | /** |
762 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 |
907 | * r100_cs_packet_next_reloc() - parse next packet which should be reloc packet3 |
763 | * @parser: parser structure holding parsing context. |
908 | * @parser: parser structure holding parsing context. |
764 | * @data: pointer to relocation data |
909 | * @data: pointer to relocation data |
765 | * @offset_start: starting offset |
910 | * @offset_start: starting offset |
Line 806... | Line 951... | ||
806 | /* FIXME: we assume reloc size is 4 dwords */ |
951 | /* FIXME: we assume reloc size is 4 dwords */ |
807 | *cs_reloc = p->relocs_ptr[(idx / 4)]; |
952 | *cs_reloc = p->relocs_ptr[(idx / 4)]; |
808 | return 0; |
953 | return 0; |
809 | } |
954 | } |
Line -... | Line 955... | ||
- | 955 | ||
- | 956 | static int r100_get_vtx_size(uint32_t vtx_fmt) |
|
- | 957 | { |
|
- | 958 | int vtx_size; |
|
- | 959 | vtx_size = 2; |
|
- | 960 | /* ordered according to bits in spec */ |
|
- | 961 | if (vtx_fmt & RADEON_SE_VTX_FMT_W0) |
|
- | 962 | vtx_size++; |
|
- | 963 | if (vtx_fmt & RADEON_SE_VTX_FMT_FPCOLOR) |
|
- | 964 | vtx_size += 3; |
|
- | 965 | if (vtx_fmt & RADEON_SE_VTX_FMT_FPALPHA) |
|
- | 966 | vtx_size++; |
|
- | 967 | if (vtx_fmt & RADEON_SE_VTX_FMT_PKCOLOR) |
|
- | 968 | vtx_size++; |
|
- | 969 | if (vtx_fmt & RADEON_SE_VTX_FMT_FPSPEC) |
|
- | 970 | vtx_size += 3; |
|
- | 971 | if (vtx_fmt & RADEON_SE_VTX_FMT_FPFOG) |
|
- | 972 | vtx_size++; |
|
- | 973 | if (vtx_fmt & RADEON_SE_VTX_FMT_PKSPEC) |
|
- | 974 | vtx_size++; |
|
- | 975 | if (vtx_fmt & RADEON_SE_VTX_FMT_ST0) |
|
- | 976 | vtx_size += 2; |
|
- | 977 | if (vtx_fmt & RADEON_SE_VTX_FMT_ST1) |
|
- | 978 | vtx_size += 2; |
|
- | 979 | if (vtx_fmt & RADEON_SE_VTX_FMT_Q1) |
|
- | 980 | vtx_size++; |
|
- | 981 | if (vtx_fmt & RADEON_SE_VTX_FMT_ST2) |
|
- | 982 | vtx_size += 2; |
|
- | 983 | if (vtx_fmt & RADEON_SE_VTX_FMT_Q2) |
|
- | 984 | vtx_size++; |
|
- | 985 | if (vtx_fmt & RADEON_SE_VTX_FMT_ST3) |
|
- | 986 | vtx_size += 2; |
|
- | 987 | if (vtx_fmt & RADEON_SE_VTX_FMT_Q3) |
|
- | 988 | vtx_size++; |
|
- | 989 | if (vtx_fmt & RADEON_SE_VTX_FMT_Q0) |
|
- | 990 | vtx_size++; |
|
- | 991 | /* blend weight */ |
|
- | 992 | if (vtx_fmt & (0x7 << 15)) |
|
- | 993 | vtx_size += (vtx_fmt >> 15) & 0x7; |
|
- | 994 | if (vtx_fmt & RADEON_SE_VTX_FMT_N0) |
|
- | 995 | vtx_size += 3; |
|
- | 996 | if (vtx_fmt & RADEON_SE_VTX_FMT_XY1) |
|
- | 997 | vtx_size += 2; |
|
- | 998 | if (vtx_fmt & RADEON_SE_VTX_FMT_Z1) |
|
- | 999 | vtx_size++; |
|
- | 1000 | if (vtx_fmt & RADEON_SE_VTX_FMT_W1) |
|
- | 1001 | vtx_size++; |
|
- | 1002 | if (vtx_fmt & RADEON_SE_VTX_FMT_N1) |
|
- | 1003 | vtx_size++; |
|
- | 1004 | if (vtx_fmt & RADEON_SE_VTX_FMT_Z) |
|
- | 1005 | vtx_size++; |
|
- | 1006 | return vtx_size; |
|
- | 1007 | } |
|
810 | 1008 | ||
811 | static int r100_packet0_check(struct radeon_cs_parser *p, |
1009 | static int r100_packet0_check(struct radeon_cs_parser *p, |
- | 1010 | struct radeon_cs_packet *pkt, |
|
812 | struct radeon_cs_packet *pkt) |
1011 | unsigned idx, unsigned reg) |
813 | { |
1012 | { |
814 | struct radeon_cs_chunk *ib_chunk; |
1013 | struct radeon_cs_chunk *ib_chunk; |
- | 1014 | struct radeon_cs_reloc *reloc; |
|
815 | struct radeon_cs_reloc *reloc; |
1015 | struct r100_cs_track *track; |
816 | volatile uint32_t *ib; |
1016 | volatile uint32_t *ib; |
817 | uint32_t tmp; |
- | |
818 | unsigned reg; |
- | |
819 | unsigned i; |
- | |
820 | unsigned idx; |
- | |
821 | bool onereg; |
1017 | uint32_t tmp; |
- | 1018 | int r; |
|
- | 1019 | int i, face; |
|
Line 822... | Line 1020... | ||
822 | int r; |
1020 | u32 tile_flags = 0; |
823 | 1021 | ||
824 | ib = p->ib->ptr; |
- | |
825 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
- | |
826 | idx = pkt->idx + 1; |
- | |
827 | reg = pkt->reg; |
1022 | ib = p->ib->ptr; |
828 | onereg = false; |
- | |
829 | if (CP_PACKET0_GET_ONE_REG_WR(ib_chunk->kdata[pkt->idx])) { |
1023 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
830 | onereg = true; |
- | |
831 | } |
1024 | track = (struct r100_cs_track *)p->track; |
- | 1025 | ||
- | 1026 | switch (reg) { |
|
- | 1027 | case RADEON_CRTC_GUI_TRIG_VLINE: |
|
- | 1028 | r = r100_cs_packet_parse_vline(p); |
|
- | 1029 | if (r) { |
|
- | 1030 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1031 | idx, reg); |
|
- | 1032 | r100_cs_dump_packet(p, pkt); |
|
- | 1033 | return r; |
|
832 | for (i = 0; i <= pkt->count; i++, idx++, reg += 4) { |
1034 | } |
833 | switch (reg) { |
1035 | break; |
834 | /* FIXME: only allow PACKET3 blit? easier to check for out of |
1036 | /* FIXME: only allow PACKET3 blit? easier to check for out of |
835 | * range access */ |
1037 | * range access */ |
- | 1038 | case RADEON_DST_PITCH_OFFSET: |
|
- | 1039 | case RADEON_SRC_PITCH_OFFSET: |
|
- | 1040 | r = r100_reloc_pitch_offset(p, pkt, idx, reg); |
|
- | 1041 | if (r) |
|
- | 1042 | return r; |
|
836 | case RADEON_DST_PITCH_OFFSET: |
1043 | break; |
837 | case RADEON_SRC_PITCH_OFFSET: |
1044 | case RADEON_RB3D_DEPTHOFFSET: |
838 | r = r100_cs_packet_next_reloc(p, &reloc); |
1045 | r = r100_cs_packet_next_reloc(p, &reloc); |
839 | if (r) { |
1046 | if (r) { |
840 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1047 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
841 | idx, reg); |
1048 | idx, reg); |
842 | r100_cs_dump_packet(p, pkt); |
1049 | r100_cs_dump_packet(p, pkt); |
843 | return r; |
1050 | return r; |
844 | } |
1051 | } |
845 | tmp = ib_chunk->kdata[idx] & 0x003fffff; |
1052 | track->zb.robj = reloc->robj; |
846 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); |
1053 | track->zb.offset = ib_chunk->kdata[idx]; |
847 | ib[idx] = (ib_chunk->kdata[idx] & 0xffc00000) | tmp; |
- | |
848 | break; |
1054 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
849 | case RADEON_RB3D_DEPTHOFFSET: |
1055 | break; |
850 | case RADEON_RB3D_COLOROFFSET: |
1056 | case RADEON_RB3D_COLOROFFSET: |
851 | case R300_RB3D_COLOROFFSET0: |
1057 | r = r100_cs_packet_next_reloc(p, &reloc); |
852 | case R300_ZB_DEPTHOFFSET: |
1058 | if (r) { |
853 | case R200_PP_TXOFFSET_0: |
1059 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
854 | case R200_PP_TXOFFSET_1: |
1060 | idx, reg); |
- | 1061 | r100_cs_dump_packet(p, pkt); |
|
855 | case R200_PP_TXOFFSET_2: |
1062 | return r; |
856 | case R200_PP_TXOFFSET_3: |
1063 | } |
- | 1064 | track->cb[0].robj = reloc->robj; |
|
- | 1065 | track->cb[0].offset = ib_chunk->kdata[idx]; |
|
857 | case R200_PP_TXOFFSET_4: |
1066 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
858 | case R200_PP_TXOFFSET_5: |
1067 | break; |
859 | case RADEON_PP_TXOFFSET_0: |
1068 | case RADEON_PP_TXOFFSET_0: |
860 | case RADEON_PP_TXOFFSET_1: |
1069 | case RADEON_PP_TXOFFSET_1: |
- | 1070 | case RADEON_PP_TXOFFSET_2: |
|
- | 1071 | i = (reg - RADEON_PP_TXOFFSET_0) / 24; |
|
- | 1072 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 1073 | if (r) { |
|
- | 1074 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1075 | idx, reg); |
|
- | 1076 | r100_cs_dump_packet(p, pkt); |
|
- | 1077 | return r; |
|
- | 1078 | } |
|
- | 1079 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
|
861 | case RADEON_PP_TXOFFSET_2: |
1080 | track->textures[i].robj = reloc->robj; |
862 | case R300_TX_OFFSET_0: |
1081 | break; |
863 | case R300_TX_OFFSET_0+4: |
1082 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
864 | case R300_TX_OFFSET_0+8: |
1083 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
865 | case R300_TX_OFFSET_0+12: |
1084 | case RADEON_PP_CUBIC_OFFSET_T0_2: |
- | 1085 | case RADEON_PP_CUBIC_OFFSET_T0_3: |
|
- | 1086 | case RADEON_PP_CUBIC_OFFSET_T0_4: |
|
- | 1087 | i = (reg - RADEON_PP_CUBIC_OFFSET_T0_0) / 4; |
|
- | 1088 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 1089 | if (r) { |
|
- | 1090 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1091 | idx, reg); |
|
- | 1092 | r100_cs_dump_packet(p, pkt); |
|
- | 1093 | return r; |
|
- | 1094 | } |
|
- | 1095 | track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx]; |
|
- | 1096 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
|
866 | case R300_TX_OFFSET_0+16: |
1097 | track->textures[0].cube_info[i].robj = reloc->robj; |
867 | case R300_TX_OFFSET_0+20: |
1098 | break; |
868 | case R300_TX_OFFSET_0+24: |
1099 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
869 | case R300_TX_OFFSET_0+28: |
1100 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
870 | case R300_TX_OFFSET_0+32: |
1101 | case RADEON_PP_CUBIC_OFFSET_T1_2: |
- | 1102 | case RADEON_PP_CUBIC_OFFSET_T1_3: |
|
- | 1103 | case RADEON_PP_CUBIC_OFFSET_T1_4: |
|
- | 1104 | i = (reg - RADEON_PP_CUBIC_OFFSET_T1_0) / 4; |
|
- | 1105 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 1106 | if (r) { |
|
- | 1107 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1108 | idx, reg); |
|
- | 1109 | r100_cs_dump_packet(p, pkt); |
|
- | 1110 | return r; |
|
- | 1111 | } |
|
- | 1112 | track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx]; |
|
- | 1113 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
|
871 | case R300_TX_OFFSET_0+36: |
1114 | track->textures[1].cube_info[i].robj = reloc->robj; |
872 | case R300_TX_OFFSET_0+40: |
1115 | break; |
873 | case R300_TX_OFFSET_0+44: |
1116 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
874 | case R300_TX_OFFSET_0+48: |
1117 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
875 | case R300_TX_OFFSET_0+52: |
1118 | case RADEON_PP_CUBIC_OFFSET_T2_2: |
- | 1119 | case RADEON_PP_CUBIC_OFFSET_T2_3: |
|
876 | case R300_TX_OFFSET_0+56: |
1120 | case RADEON_PP_CUBIC_OFFSET_T2_4: |
877 | case R300_TX_OFFSET_0+60: |
1121 | i = (reg - RADEON_PP_CUBIC_OFFSET_T2_0) / 4; |
878 | r = r100_cs_packet_next_reloc(p, &reloc); |
1122 | r = r100_cs_packet_next_reloc(p, &reloc); |
879 | if (r) { |
1123 | if (r) { |
880 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1124 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
881 | idx, reg); |
1125 | idx, reg); |
882 | r100_cs_dump_packet(p, pkt); |
1126 | r100_cs_dump_packet(p, pkt); |
- | 1127 | return r; |
|
883 | return r; |
1128 | } |
- | 1129 | track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx]; |
|
- | 1130 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
|
- | 1131 | track->textures[2].cube_info[i].robj = reloc->robj; |
|
- | 1132 | break; |
|
- | 1133 | case RADEON_RE_WIDTH_HEIGHT: |
|
- | 1134 | track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); |
|
- | 1135 | break; |
|
- | 1136 | case RADEON_RB3D_COLORPITCH: |
|
- | 1137 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 1138 | if (r) { |
|
- | 1139 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1140 | idx, reg); |
|
- | 1141 | r100_cs_dump_packet(p, pkt); |
|
- | 1142 | return r; |
|
- | 1143 | } |
|
- | 1144 | ||
- | 1145 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
|
- | 1146 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
|
- | 1147 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
|
- | 1148 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
|
- | 1149 | ||
- | 1150 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); |
|
- | 1151 | tmp |= tile_flags; |
|
- | 1152 | ib[idx] = tmp; |
|
- | 1153 | ||
- | 1154 | track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; |
|
- | 1155 | break; |
|
- | 1156 | case RADEON_RB3D_DEPTHPITCH: |
|
- | 1157 | track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; |
|
- | 1158 | break; |
|
- | 1159 | case RADEON_RB3D_CNTL: |
|
- | 1160 | switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
|
- | 1161 | case 7: |
|
- | 1162 | case 8: |
|
- | 1163 | case 9: |
|
- | 1164 | case 11: |
|
- | 1165 | case 12: |
|
- | 1166 | track->cb[0].cpp = 1; |
|
- | 1167 | break; |
|
- | 1168 | case 3: |
|
- | 1169 | case 4: |
|
- | 1170 | case 15: |
|
- | 1171 | track->cb[0].cpp = 2; |
|
- | 1172 | break; |
|
- | 1173 | case 6: |
|
- | 1174 | track->cb[0].cpp = 4; |
|
- | 1175 | break; |
|
- | 1176 | default: |
|
- | 1177 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
|
- | 1178 | ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
|
- | 1179 | return -EINVAL; |
|
- | 1180 | } |
|
- | 1181 | track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); |
|
- | 1182 | break; |
|
- | 1183 | case RADEON_RB3D_ZSTENCILCNTL: |
|
- | 1184 | switch (ib_chunk->kdata[idx] & 0xf) { |
|
- | 1185 | case 0: |
|
- | 1186 | track->zb.cpp = 2; |
|
- | 1187 | break; |
|
- | 1188 | case 2: |
|
- | 1189 | case 3: |
|
- | 1190 | case 4: |
|
- | 1191 | case 5: |
|
- | 1192 | case 9: |
|
884 | } |
1193 | case 11: |
885 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1194 | track->zb.cpp = 4; |
886 | break; |
- | |
887 | default: |
1195 | break; |
888 | /* FIXME: we don't want to allow anyothers packet */ |
1196 | default: |
889 | break; |
- | |
890 | } |
- | |
891 | if (onereg) { |
1197 | break; |
- | 1198 | } |
|
- | 1199 | break; |
|
- | 1200 | case RADEON_RB3D_ZPASS_ADDR: |
|
- | 1201 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 1202 | if (r) { |
|
- | 1203 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 1204 | idx, reg); |
|
- | 1205 | r100_cs_dump_packet(p, pkt); |
|
- | 1206 | return r; |
|
- | 1207 | } |
|
- | 1208 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
|
- | 1209 | break; |
|
- | 1210 | case RADEON_PP_CNTL: |
|
- | 1211 | { |
|
- | 1212 | uint32_t temp = ib_chunk->kdata[idx] >> 4; |
|
- | 1213 | for (i = 0; i < track->num_texture; i++) |
|
- | 1214 | track->textures[i].enabled = !!(temp & (1 << i)); |
|
- | 1215 | } |
|
- | 1216 | break; |
|
- | 1217 | case RADEON_SE_VF_CNTL: |
|
- | 1218 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
|
- | 1219 | break; |
|
- | 1220 | case RADEON_SE_VTX_FMT: |
|
- | 1221 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]); |
|
- | 1222 | break; |
|
- | 1223 | case RADEON_PP_TEX_SIZE_0: |
|
- | 1224 | case RADEON_PP_TEX_SIZE_1: |
|
- | 1225 | case RADEON_PP_TEX_SIZE_2: |
|
- | 1226 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
|
- | 1227 | track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; |
|
- | 1228 | track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
|
- | 1229 | break; |
|
- | 1230 | case RADEON_PP_TEX_PITCH_0: |
|
- | 1231 | case RADEON_PP_TEX_PITCH_1: |
|
- | 1232 | case RADEON_PP_TEX_PITCH_2: |
|
- | 1233 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
|
- | 1234 | track->textures[i].pitch = ib_chunk->kdata[idx] + 32; |
|
- | 1235 | break; |
|
- | 1236 | case RADEON_PP_TXFILTER_0: |
|
- | 1237 | case RADEON_PP_TXFILTER_1: |
|
- | 1238 | case RADEON_PP_TXFILTER_2: |
|
- | 1239 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
|
- | 1240 | track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK) |
|
- | 1241 | >> RADEON_MAX_MIP_LEVEL_SHIFT); |
|
- | 1242 | tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; |
|
- | 1243 | if (tmp == 2 || tmp == 6) |
|
- | 1244 | track->textures[i].roundup_w = false; |
|
- | 1245 | tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; |
|
- | 1246 | if (tmp == 2 || tmp == 6) |
|
- | 1247 | track->textures[i].roundup_h = false; |
|
- | 1248 | break; |
|
- | 1249 | case RADEON_PP_TXFORMAT_0: |
|
- | 1250 | case RADEON_PP_TXFORMAT_1: |
|
- | 1251 | case RADEON_PP_TXFORMAT_2: |
|
- | 1252 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
|
- | 1253 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) { |
|
- | 1254 | track->textures[i].use_pitch = 1; |
|
- | 1255 | } else { |
|
- | 1256 | track->textures[i].use_pitch = 0; |
|
- | 1257 | track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
|
- | 1258 | track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
|
- | 1259 | } |
|
- | 1260 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) |
|
- | 1261 | track->textures[i].tex_coord_type = 2; |
|
- | 1262 | switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { |
|
- | 1263 | case RADEON_TXFORMAT_I8: |
|
- | 1264 | case RADEON_TXFORMAT_RGB332: |
|
- | 1265 | case RADEON_TXFORMAT_Y8: |
|
- | 1266 | track->textures[i].cpp = 1; |
|
- | 1267 | break; |
|
- | 1268 | case RADEON_TXFORMAT_AI88: |
|
- | 1269 | case RADEON_TXFORMAT_ARGB1555: |
|
- | 1270 | case RADEON_TXFORMAT_RGB565: |
|
- | 1271 | case RADEON_TXFORMAT_ARGB4444: |
|
- | 1272 | case RADEON_TXFORMAT_VYUY422: |
|
- | 1273 | case RADEON_TXFORMAT_YVYU422: |
|
- | 1274 | case RADEON_TXFORMAT_DXT1: |
|
- | 1275 | case RADEON_TXFORMAT_SHADOW16: |
|
- | 1276 | case RADEON_TXFORMAT_LDUDV655: |
|
- | 1277 | case RADEON_TXFORMAT_DUDV88: |
|
- | 1278 | track->textures[i].cpp = 2; |
|
- | 1279 | break; |
|
- | 1280 | case RADEON_TXFORMAT_ARGB8888: |
|
- | 1281 | case RADEON_TXFORMAT_RGBA8888: |
|
- | 1282 | case RADEON_TXFORMAT_DXT23: |
|
- | 1283 | case RADEON_TXFORMAT_DXT45: |
|
- | 1284 | case RADEON_TXFORMAT_SHADOW32: |
|
- | 1285 | case RADEON_TXFORMAT_LDUDUV8888: |
|
- | 1286 | track->textures[i].cpp = 4; |
|
- | 1287 | break; |
|
- | 1288 | } |
|
- | 1289 | track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); |
|
- | 1290 | track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); |
|
- | 1291 | break; |
|
- | 1292 | case RADEON_PP_CUBIC_FACES_0: |
|
- | 1293 | case RADEON_PP_CUBIC_FACES_1: |
|
- | 1294 | case RADEON_PP_CUBIC_FACES_2: |
|
- | 1295 | tmp = ib_chunk->kdata[idx]; |
|
- | 1296 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
|
- | 1297 | for (face = 0; face < 4; face++) { |
|
892 | /* FIXME: forbid onereg write to register on relocate */ |
1298 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
- | 1299 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
|
- | 1300 | } |
|
- | 1301 | break; |
|
- | 1302 | default: |
|
- | 1303 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
|
893 | break; |
1304 | reg, idx); |
894 | } |
1305 | return -EINVAL; |
895 | } |
1306 | } |
Line 896... | Line 1307... | ||
896 | return 0; |
1307 | return 0; |
Line 918... | Line 1329... | ||
918 | static int r100_packet3_check(struct radeon_cs_parser *p, |
1329 | static int r100_packet3_check(struct radeon_cs_parser *p, |
919 | struct radeon_cs_packet *pkt) |
1330 | struct radeon_cs_packet *pkt) |
920 | { |
1331 | { |
921 | struct radeon_cs_chunk *ib_chunk; |
1332 | struct radeon_cs_chunk *ib_chunk; |
922 | struct radeon_cs_reloc *reloc; |
1333 | struct radeon_cs_reloc *reloc; |
- | 1334 | struct r100_cs_track *track; |
|
923 | unsigned idx; |
1335 | unsigned idx; |
924 | unsigned i, c; |
1336 | unsigned i, c; |
925 | volatile uint32_t *ib; |
1337 | volatile uint32_t *ib; |
926 | int r; |
1338 | int r; |
Line 927... | Line 1339... | ||
927 | 1339 | ||
928 | ib = p->ib->ptr; |
1340 | ib = p->ib->ptr; |
929 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
1341 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
- | 1342 | idx = pkt->idx + 1; |
|
930 | idx = pkt->idx + 1; |
1343 | track = (struct r100_cs_track *)p->track; |
931 | switch (pkt->opcode) { |
1344 | switch (pkt->opcode) { |
932 | case PACKET3_3D_LOAD_VBPNTR: |
1345 | case PACKET3_3D_LOAD_VBPNTR: |
- | 1346 | c = ib_chunk->kdata[idx++]; |
|
933 | c = ib_chunk->kdata[idx++]; |
1347 | track->num_arrays = c; |
934 | for (i = 0; i < (c - 1); i += 2, idx += 3) { |
1348 | for (i = 0; i < (c - 1); i += 2, idx += 3) { |
935 | r = r100_cs_packet_next_reloc(p, &reloc); |
1349 | r = r100_cs_packet_next_reloc(p, &reloc); |
936 | if (r) { |
1350 | if (r) { |
937 | DRM_ERROR("No reloc for packet3 %d\n", |
1351 | DRM_ERROR("No reloc for packet3 %d\n", |
938 | pkt->opcode); |
1352 | pkt->opcode); |
939 | r100_cs_dump_packet(p, pkt); |
1353 | r100_cs_dump_packet(p, pkt); |
940 | return r; |
1354 | return r; |
941 | } |
1355 | } |
- | 1356 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
|
- | 1357 | track->arrays[i + 0].robj = reloc->robj; |
|
- | 1358 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; |
|
942 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
1359 | track->arrays[i + 0].esize &= 0x7F; |
943 | r = r100_cs_packet_next_reloc(p, &reloc); |
1360 | r = r100_cs_packet_next_reloc(p, &reloc); |
944 | if (r) { |
1361 | if (r) { |
945 | DRM_ERROR("No reloc for packet3 %d\n", |
1362 | DRM_ERROR("No reloc for packet3 %d\n", |
946 | pkt->opcode); |
1363 | pkt->opcode); |
947 | r100_cs_dump_packet(p, pkt); |
1364 | r100_cs_dump_packet(p, pkt); |
948 | return r; |
1365 | return r; |
949 | } |
1366 | } |
- | 1367 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); |
|
- | 1368 | track->arrays[i + 1].robj = reloc->robj; |
|
- | 1369 | track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; |
|
950 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); |
1370 | track->arrays[i + 1].esize &= 0x7F; |
951 | } |
1371 | } |
952 | if (c & 1) { |
1372 | if (c & 1) { |
953 | r = r100_cs_packet_next_reloc(p, &reloc); |
1373 | r = r100_cs_packet_next_reloc(p, &reloc); |
954 | if (r) { |
1374 | if (r) { |
955 | DRM_ERROR("No reloc for packet3 %d\n", |
1375 | DRM_ERROR("No reloc for packet3 %d\n", |
956 | pkt->opcode); |
1376 | pkt->opcode); |
957 | r100_cs_dump_packet(p, pkt); |
1377 | r100_cs_dump_packet(p, pkt); |
958 | return r; |
1378 | return r; |
959 | } |
1379 | } |
- | 1380 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
|
- | 1381 | track->arrays[i + 0].robj = reloc->robj; |
|
- | 1382 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; |
|
960 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
1383 | track->arrays[i + 0].esize &= 0x7F; |
961 | } |
1384 | } |
962 | break; |
1385 | break; |
963 | case PACKET3_INDX_BUFFER: |
1386 | case PACKET3_INDX_BUFFER: |
964 | r = r100_cs_packet_next_reloc(p, &reloc); |
1387 | r = r100_cs_packet_next_reloc(p, &reloc); |
Line 972... | Line 1395... | ||
972 | if (r) { |
1395 | if (r) { |
973 | return r; |
1396 | return r; |
974 | } |
1397 | } |
975 | break; |
1398 | break; |
976 | case 0x23: |
1399 | case 0x23: |
977 | /* FIXME: cleanup */ |
- | |
978 | /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ |
1400 | /* 3D_RNDR_GEN_INDX_PRIM on r100/r200 */ |
979 | r = r100_cs_packet_next_reloc(p, &reloc); |
1401 | r = r100_cs_packet_next_reloc(p, &reloc); |
980 | if (r) { |
1402 | if (r) { |
981 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
1403 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
982 | r100_cs_dump_packet(p, pkt); |
1404 | r100_cs_dump_packet(p, pkt); |
983 | return r; |
1405 | return r; |
984 | } |
1406 | } |
985 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1407 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
- | 1408 | track->num_arrays = 1; |
|
- | 1409 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]); |
|
- | 1410 | ||
- | 1411 | track->arrays[0].robj = reloc->robj; |
|
- | 1412 | track->arrays[0].esize = track->vtx_size; |
|
- | 1413 | ||
- | 1414 | track->max_indx = ib_chunk->kdata[idx+1]; |
|
- | 1415 | ||
- | 1416 | track->vap_vf_cntl = ib_chunk->kdata[idx+3]; |
|
- | 1417 | track->immd_dwords = pkt->count - 1; |
|
- | 1418 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1419 | if (r) |
|
- | 1420 | return r; |
|
986 | break; |
1421 | break; |
987 | case PACKET3_3D_DRAW_IMMD: |
1422 | case PACKET3_3D_DRAW_IMMD: |
- | 1423 | if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { |
|
- | 1424 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
|
- | 1425 | return -EINVAL; |
|
- | 1426 | } |
|
- | 1427 | track->vap_vf_cntl = ib_chunk->kdata[idx+1]; |
|
- | 1428 | track->immd_dwords = pkt->count - 1; |
|
- | 1429 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1430 | if (r) |
|
- | 1431 | return r; |
|
- | 1432 | break; |
|
988 | /* triggers drawing using in-packet vertex data */ |
1433 | /* triggers drawing using in-packet vertex data */ |
989 | case PACKET3_3D_DRAW_IMMD_2: |
1434 | case PACKET3_3D_DRAW_IMMD_2: |
- | 1435 | if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { |
|
- | 1436 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
|
- | 1437 | return -EINVAL; |
|
- | 1438 | } |
|
- | 1439 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
|
- | 1440 | track->immd_dwords = pkt->count; |
|
- | 1441 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1442 | if (r) |
|
- | 1443 | return r; |
|
- | 1444 | break; |
|
990 | /* triggers drawing using in-packet vertex data */ |
1445 | /* triggers drawing using in-packet vertex data */ |
991 | case PACKET3_3D_DRAW_VBUF_2: |
1446 | case PACKET3_3D_DRAW_VBUF_2: |
- | 1447 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
|
- | 1448 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1449 | if (r) |
|
- | 1450 | return r; |
|
- | 1451 | break; |
|
992 | /* triggers drawing of vertex buffers setup elsewhere */ |
1452 | /* triggers drawing of vertex buffers setup elsewhere */ |
993 | case PACKET3_3D_DRAW_INDX_2: |
1453 | case PACKET3_3D_DRAW_INDX_2: |
- | 1454 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
|
- | 1455 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1456 | if (r) |
|
- | 1457 | return r; |
|
- | 1458 | break; |
|
994 | /* triggers drawing using indices to vertex buffer */ |
1459 | /* triggers drawing using indices to vertex buffer */ |
995 | case PACKET3_3D_DRAW_VBUF: |
1460 | case PACKET3_3D_DRAW_VBUF: |
- | 1461 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; |
|
- | 1462 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1463 | if (r) |
|
- | 1464 | return r; |
|
- | 1465 | break; |
|
996 | /* triggers drawing of vertex buffers setup elsewhere */ |
1466 | /* triggers drawing of vertex buffers setup elsewhere */ |
997 | case PACKET3_3D_DRAW_INDX: |
1467 | case PACKET3_3D_DRAW_INDX: |
- | 1468 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; |
|
- | 1469 | r = r100_cs_track_check(p->rdev, track); |
|
- | 1470 | if (r) |
|
- | 1471 | return r; |
|
- | 1472 | break; |
|
998 | /* triggers drawing using indices to vertex buffer */ |
1473 | /* triggers drawing using indices to vertex buffer */ |
999 | case PACKET3_NOP: |
1474 | case PACKET3_NOP: |
1000 | break; |
1475 | break; |
1001 | default: |
1476 | default: |
1002 | DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); |
1477 | DRM_ERROR("Packet3 opcode %x not supported\n", pkt->opcode); |
Line 1006... | Line 1481... | ||
1006 | } |
1481 | } |
Line 1007... | Line 1482... | ||
1007 | 1482 | ||
1008 | int r100_cs_parse(struct radeon_cs_parser *p) |
1483 | int r100_cs_parse(struct radeon_cs_parser *p) |
1009 | { |
1484 | { |
- | 1485 | struct radeon_cs_packet pkt; |
|
1010 | struct radeon_cs_packet pkt; |
1486 | struct r100_cs_track *track; |
Line -... | Line 1487... | ||
- | 1487 | int r; |
|
- | 1488 | ||
- | 1489 | track = kzalloc(sizeof(*track), GFP_KERNEL); |
|
1011 | int r; |
1490 | r100_cs_track_clear(p->rdev, track); |
1012 | 1491 | p->track = track; |
|
1013 | do { |
1492 | do { |
1014 | r = r100_cs_packet_parse(p, &pkt, p->idx); |
1493 | r = r100_cs_packet_parse(p, &pkt, p->idx); |
1015 | if (r) { |
1494 | if (r) { |
1016 | return r; |
1495 | return r; |
1017 | } |
1496 | } |
1018 | p->idx += pkt.count + 2; |
1497 | p->idx += pkt.count + 2; |
- | 1498 | switch (pkt.type) { |
|
1019 | switch (pkt.type) { |
1499 | case PACKET_TYPE0: |
- | 1500 | if (p->rdev->family >= CHIP_R200) |
|
- | 1501 | r = r100_cs_parse_packet0(p, &pkt, |
|
- | 1502 | p->rdev->config.r100.reg_safe_bm, |
|
- | 1503 | p->rdev->config.r100.reg_safe_bm_size, |
|
- | 1504 | &r200_packet0_check); |
|
- | 1505 | else |
|
- | 1506 | r = r100_cs_parse_packet0(p, &pkt, |
|
- | 1507 | p->rdev->config.r100.reg_safe_bm, |
|
1020 | case PACKET_TYPE0: |
1508 | p->rdev->config.r100.reg_safe_bm_size, |
1021 | r = r100_packet0_check(p, &pkt); |
1509 | &r100_packet0_check); |
1022 | break; |
1510 | break; |
1023 | case PACKET_TYPE2: |
1511 | case PACKET_TYPE2: |
1024 | break; |
1512 | break; |
Line 1055... | Line 1543... | ||
1055 | rdev->family == CHIP_RS200) { |
1543 | rdev->family == CHIP_RS200) { |
1056 | rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY; |
1544 | rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY; |
1057 | } |
1545 | } |
1058 | } |
1546 | } |
Line 1059... | Line -... | ||
1059 | - | ||
1060 | - | ||
1061 | 1547 | ||
1062 | /* Wait for vertical sync on primary CRTC */ |
1548 | /* Wait for vertical sync on primary CRTC */ |
1063 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev) |
1549 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev) |
1064 | { |
1550 | { |
1065 | uint32_t crtc_gen_cntl, tmp; |
1551 | uint32_t crtc_gen_cntl, tmp; |
Line 1161... | Line 1647... | ||
1161 | 1647 | ||
1162 | void r100_hdp_reset(struct radeon_device *rdev) |
1648 | void r100_hdp_reset(struct radeon_device *rdev) |
1163 | { |
1649 | { |
Line 1164... | Line 1650... | ||
1164 | uint32_t tmp; |
1650 | uint32_t tmp; |
Line 1165... | Line 1651... | ||
1165 | 1651 | ||
1166 | dbgprintf("%s\n",__FUNCTION__); |
1652 | ENTER(); |
1167 | 1653 | ||
1168 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; |
1654 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; |
Line 1178... | Line 1664... | ||
1178 | int r100_rb2d_reset(struct radeon_device *rdev) |
1664 | int r100_rb2d_reset(struct radeon_device *rdev) |
1179 | { |
1665 | { |
1180 | uint32_t tmp; |
1666 | uint32_t tmp; |
1181 | int i; |
1667 | int i; |
Line 1182... | Line 1668... | ||
1182 | 1668 | ||
Line 1183... | Line 1669... | ||
1183 | dbgprintf("%s\n",__FUNCTION__); |
1669 | ENTER(); |
1184 | 1670 | ||
1185 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2); |
1671 | WREG32(RADEON_RBBM_SOFT_RESET, RADEON_SOFT_RESET_E2); |
1186 | (void)RREG32(RADEON_RBBM_SOFT_RESET); |
1672 | (void)RREG32(RADEON_RBBM_SOFT_RESET); |
Line 1267... | Line 1753... | ||
1267 | /* newer IGPs */ |
1753 | /* newer IGPs */ |
1268 | rdev->mc.vram_width = 128; |
1754 | rdev->mc.vram_width = 128; |
1269 | } |
1755 | } |
1270 | } |
1756 | } |
Line 1271... | Line 1757... | ||
1271 | 1757 | ||
1272 | void r100_vram_info(struct radeon_device *rdev) |
1758 | static u32 r100_get_accessible_vram(struct radeon_device *rdev) |
- | 1759 | { |
|
- | 1760 | u32 aper_size; |
|
- | 1761 | u8 byte; |
|
- | 1762 | ||
- | 1763 | aper_size = RREG32(RADEON_CONFIG_APER_SIZE); |
|
- | 1764 | ||
- | 1765 | /* Set HDP_APER_CNTL only on cards that are known not to be broken, |
|
- | 1766 | * that is has the 2nd generation multifunction PCI interface |
|
- | 1767 | */ |
|
- | 1768 | if (rdev->family == CHIP_RV280 || |
|
- | 1769 | rdev->family >= CHIP_RV350) { |
|
- | 1770 | WREG32_P(RADEON_HOST_PATH_CNTL, RADEON_HDP_APER_CNTL, |
|
- | 1771 | ~RADEON_HDP_APER_CNTL); |
|
1273 | { |
1772 | DRM_INFO("Generation 2 PCI interface, using max accessible memory\n"); |
- | 1773 | return aper_size * 2; |
|
- | 1774 | } |
|
- | 1775 | ||
- | 1776 | /* Older cards have all sorts of funny issues to deal with. First |
|
- | 1777 | * check if it's a multifunction card by reading the PCI config |
|
- | 1778 | * header type... Limit those to one aperture size |
|
- | 1779 | */ |
|
- | 1780 | // pci_read_config_byte(rdev->pdev, 0xe, &byte); |
|
- | 1781 | // if (byte & 0x80) { |
|
- | 1782 | // DRM_INFO("Generation 1 PCI interface in multifunction mode\n"); |
|
- | 1783 | // DRM_INFO("Limiting VRAM to one aperture\n"); |
|
- | 1784 | // return aper_size; |
|
- | 1785 | // } |
|
- | 1786 | ||
- | 1787 | /* Single function older card. We read HDP_APER_CNTL to see how the BIOS |
|
- | 1788 | * have set it up. We don't write this as it's broken on some ASICs but |
|
- | 1789 | * we expect the BIOS to have done the right thing (might be too optimistic...) |
|
- | 1790 | */ |
|
- | 1791 | if (RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL) |
|
- | 1792 | return aper_size * 2; |
|
- | 1793 | return aper_size; |
|
- | 1794 | } |
|
- | 1795 | ||
- | 1796 | void r100_vram_init_sizes(struct radeon_device *rdev) |
|
- | 1797 | { |
|
- | 1798 | u64 config_aper_size; |
|
- | 1799 | u32 accessible; |
|
- | 1800 | ||
Line 1274... | Line 1801... | ||
1274 | r100_vram_get_type(rdev); |
1801 | config_aper_size = RREG32(RADEON_CONFIG_APER_SIZE); |
1275 | 1802 | ||
1276 | if (rdev->flags & RADEON_IS_IGP) { |
1803 | if (rdev->flags & RADEON_IS_IGP) { |
1277 | uint32_t tom; |
1804 | uint32_t tom; |
1278 | /* read NB_TOM to get the amount of ram stolen for the GPU */ |
1805 | /* read NB_TOM to get the amount of ram stolen for the GPU */ |
- | 1806 | tom = RREG32(RADEON_NB_TOM); |
|
- | 1807 | rdev->mc.real_vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16); |
|
1279 | tom = RREG32(RADEON_NB_TOM); |
1808 | /* for IGPs we need to keep VRAM where it was put by the BIOS */ |
- | 1809 | rdev->mc.vram_location = (tom & 0xffff) << 16; |
|
1280 | rdev->mc.vram_size = (((tom >> 16) - (tom & 0xffff) + 1) << 16); |
1810 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
1281 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size); |
1811 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
1282 | } else { |
1812 | } else { |
1283 | rdev->mc.vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
1813 | rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE); |
1284 | /* Some production boards of m6 will report 0 |
1814 | /* Some production boards of m6 will report 0 |
1285 | * if it's 8 MB |
1815 | * if it's 8 MB |
1286 | */ |
1816 | */ |
1287 | if (rdev->mc.vram_size == 0) { |
1817 | if (rdev->mc.real_vram_size == 0) { |
1288 | rdev->mc.vram_size = 8192 * 1024; |
1818 | rdev->mc.real_vram_size = 8192 * 1024; |
- | 1819 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
|
- | 1820 | } |
|
- | 1821 | /* let driver place VRAM */ |
|
- | 1822 | rdev->mc.vram_location = 0xFFFFFFFFUL; |
|
- | 1823 | /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM - |
|
- | 1824 | * Novell bug 204882 + along with lots of ubuntu ones */ |
|
- | 1825 | if (config_aper_size > rdev->mc.real_vram_size) |
|
- | 1826 | rdev->mc.mc_vram_size = config_aper_size; |
|
1289 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size); |
1827 | else |
Line -... | Line 1828... | ||
- | 1828 | rdev->mc.mc_vram_size = rdev->mc.real_vram_size; |
|
- | 1829 | } |
|
- | 1830 | ||
1290 | } |
1831 | /* work out accessible VRAM */ |
1291 | } |
1832 | accessible = r100_get_accessible_vram(rdev); |
- | 1833 | ||
- | 1834 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
|
- | 1835 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
|
- | 1836 | ||
- | 1837 | if (accessible > rdev->mc.aper_size) |
|
- | 1838 | accessible = rdev->mc.aper_size; |
|
- | 1839 | ||
- | 1840 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) |
|
- | 1841 | rdev->mc.mc_vram_size = rdev->mc.aper_size; |
|
- | 1842 | ||
- | 1843 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) |
|
- | 1844 | rdev->mc.real_vram_size = rdev->mc.aper_size; |
|
- | 1845 | } |
|
- | 1846 | ||
- | 1847 | void r100_vga_set_state(struct radeon_device *rdev, bool state) |
|
- | 1848 | { |
|
- | 1849 | uint32_t temp; |
|
- | 1850 | ||
- | 1851 | temp = RREG32(RADEON_CONFIG_CNTL); |
|
- | 1852 | if (state == false) { |
|
- | 1853 | temp &= ~(1<<8); |
|
- | 1854 | temp |= (1<<9); |
|
- | 1855 | } else { |
|
- | 1856 | temp &= ~(1<<9); |
|
- | 1857 | } |
|
- | 1858 | WREG32(RADEON_CONFIG_CNTL, temp); |
|
- | 1859 | } |
|
- | 1860 | ||
- | 1861 | void r100_vram_info(struct radeon_device *rdev) |
|
- | 1862 | { |
|
1292 | 1863 | r100_vram_get_type(rdev); |
|
Line -... | Line 1864... | ||
- | 1864 | ||
1293 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
1865 | r100_vram_init_sizes(rdev); |
1294 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
1866 | } |
1295 | } |
1867 | |
1296 | 1868 | ||
1297 | /* |
1869 | /* |
Line 1348... | Line 1920... | ||
1348 | r100_pll_errata_after_index(rdev); |
1920 | r100_pll_errata_after_index(rdev); |
1349 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
1921 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
1350 | r100_pll_errata_after_data(rdev); |
1922 | r100_pll_errata_after_data(rdev); |
1351 | } |
1923 | } |
Line 1352... | Line -... | ||
1352 | - | ||
1353 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) |
- | |
1354 | { |
- | |
1355 | if (reg < 0x10000) |
- | |
1356 | return readl(((void __iomem *)rdev->rmmio) + reg); |
- | |
1357 | else { |
- | |
1358 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
- | |
1359 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); |
- | |
1360 | } |
- | |
1361 | } |
- | |
1362 | - | ||
1363 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
- | |
1364 | { |
- | |
1365 | if (reg < 0x10000) |
- | |
1366 | writel(v, ((void __iomem *)rdev->rmmio) + reg); |
- | |
1367 | else { |
- | |
1368 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
- | |
1369 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); |
- | |
1370 | } |
- | |
1371 | } |
- | |
1372 | 1924 | ||
1373 | int r100_init(struct radeon_device *rdev) |
1925 | int r100_init(struct radeon_device *rdev) |
- | 1926 | { |
|
- | 1927 | if (ASIC_IS_RN50(rdev)) { |
|
- | 1928 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
|
- | 1929 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); |
|
- | 1930 | } else if (rdev->family < CHIP_R200) { |
|
- | 1931 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; |
|
- | 1932 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); |
|
- | 1933 | } else { |
|
- | 1934 | return r200_init(rdev); |
|
1374 | { |
1935 | } |
1375 | return 0; |
1936 | return 0; |
Line 1376... | Line 1937... | ||
1376 | } |
1937 | } |
1377 | 1938 | ||
Line 1543... | Line 2104... | ||
1543 | return radeon_debugfs_add_files(rdev, r100_debugfs_mc_info_list, 1); |
2104 | return radeon_debugfs_add_files(rdev, r100_debugfs_mc_info_list, 1); |
1544 | #else |
2105 | #else |
1545 | return 0; |
2106 | return 0; |
1546 | #endif |
2107 | #endif |
1547 | }><>>><>=>><>>=>>>>><>=>><>><>><>><>><>><>>><>><>>><>>>>>>>=>=>><>=>><>><>>><>><>><>><>>>>>>>>><>><>><>><>><>><>><>><>><>> |
2108 | } |
- | 2109 | ||
- | 2110 | int r100_set_surface_reg(struct radeon_device *rdev, int reg, |
|
- | 2111 | uint32_t tiling_flags, uint32_t pitch, |
|
- | 2112 | uint32_t offset, uint32_t obj_size) |
|
- | 2113 | { |
|
- | 2114 | int surf_index = reg * 16; |
|
- | 2115 | int flags = 0; |
|
- | 2116 | ||
- | 2117 | /* r100/r200 divide by 16 */ |
|
- | 2118 | if (rdev->family < CHIP_R300) |
|
- | 2119 | flags = pitch / 16; |
|
- | 2120 | else |
|
- | 2121 | flags = pitch / 8; |
|
- | 2122 | ||
- | 2123 | if (rdev->family <= CHIP_RS200) { |
|
- | 2124 | if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
|
- | 2125 | == (RADEON_TILING_MACRO|RADEON_TILING_MICRO)) |
|
- | 2126 | flags |= RADEON_SURF_TILE_COLOR_BOTH; |
|
- | 2127 | if (tiling_flags & RADEON_TILING_MACRO) |
|
- | 2128 | flags |= RADEON_SURF_TILE_COLOR_MACRO; |
|
- | 2129 | } else if (rdev->family <= CHIP_RV280) { |
|
- | 2130 | if (tiling_flags & (RADEON_TILING_MACRO)) |
|
- | 2131 | flags |= R200_SURF_TILE_COLOR_MACRO; |
|
- | 2132 | if (tiling_flags & RADEON_TILING_MICRO) |
|
- | 2133 | flags |= R200_SURF_TILE_COLOR_MICRO; |
|
- | 2134 | } else { |
|
- | 2135 | if (tiling_flags & RADEON_TILING_MACRO) |
|
- | 2136 | flags |= R300_SURF_TILE_MACRO; |
|
- | 2137 | if (tiling_flags & RADEON_TILING_MICRO) |
|
- | 2138 | flags |= R300_SURF_TILE_MICRO; |
|
- | 2139 | } |
|
- | 2140 | ||
- | 2141 | if (tiling_flags & RADEON_TILING_SWAP_16BIT) |
|
- | 2142 | flags |= RADEON_SURF_AP0_SWP_16BPP | RADEON_SURF_AP1_SWP_16BPP; |
|
- | 2143 | if (tiling_flags & RADEON_TILING_SWAP_32BIT) |
|
- | 2144 | flags |= RADEON_SURF_AP0_SWP_32BPP | RADEON_SURF_AP1_SWP_32BPP; |
|
- | 2145 | ||
- | 2146 | DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1); |
|
- | 2147 | WREG32(RADEON_SURFACE0_INFO + surf_index, flags); |
|
- | 2148 | WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset); |
|
- | 2149 | WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1); |
|
- | 2150 | return 0; |
|
- | 2151 | } |
|
- | 2152 | ||
- | 2153 | void r100_clear_surface_reg(struct radeon_device *rdev, int reg) |
|
- | 2154 | { |
|
- | 2155 | int surf_index = reg * 16; |
|
- | 2156 | WREG32(RADEON_SURFACE0_INFO + surf_index, 0); |
|
- | 2157 | } |
|
- | 2158 | ||
- | 2159 | void r100_bandwidth_update(struct radeon_device *rdev) |
|
- | 2160 | { |
|
- | 2161 | fixed20_12 trcd_ff, trp_ff, tras_ff, trbs_ff, tcas_ff; |
|
- | 2162 | fixed20_12 sclk_ff, mclk_ff, sclk_eff_ff, sclk_delay_ff; |
|
- | 2163 | fixed20_12 peak_disp_bw, mem_bw, pix_clk, pix_clk2, temp_ff, crit_point_ff; |
|
- | 2164 | uint32_t temp, data, mem_trcd, mem_trp, mem_tras; |
|
- | 2165 | fixed20_12 memtcas_ff[8] = { |
|
- | 2166 | fixed_init(1), |
|
- | 2167 | fixed_init(2), |
|
- | 2168 | fixed_init(3), |
|
- | 2169 | fixed_init(0), |
|
- | 2170 | fixed_init_half(1), |
|
- | 2171 | fixed_init_half(2), |
|
- | 2172 | fixed_init(0), |
|
- | 2173 | }; |
|
- | 2174 | fixed20_12 memtcas_rs480_ff[8] = { |
|
- | 2175 | fixed_init(0), |
|
- | 2176 | fixed_init(1), |
|
- | 2177 | fixed_init(2), |
|
- | 2178 | fixed_init(3), |
|
- | 2179 | fixed_init(0), |
|
- | 2180 | fixed_init_half(1), |
|
- | 2181 | fixed_init_half(2), |
|
- | 2182 | fixed_init_half(3), |
|
- | 2183 | }; |
|
- | 2184 | fixed20_12 memtcas2_ff[8] = { |
|
- | 2185 | fixed_init(0), |
|
- | 2186 | fixed_init(1), |
|
- | 2187 | fixed_init(2), |
|
- | 2188 | fixed_init(3), |
|
- | 2189 | fixed_init(4), |
|
- | 2190 | fixed_init(5), |
|
- | 2191 | fixed_init(6), |
|
- | 2192 | fixed_init(7), |
|
- | 2193 | }; |
|
- | 2194 | fixed20_12 memtrbs[8] = { |
|
- | 2195 | fixed_init(1), |
|
- | 2196 | fixed_init_half(1), |
|
- | 2197 | fixed_init(2), |
|
- | 2198 | fixed_init_half(2), |
|
- | 2199 | fixed_init(3), |
|
- | 2200 | fixed_init_half(3), |
|
- | 2201 | fixed_init(4), |
|
- | 2202 | fixed_init_half(4) |
|
- | 2203 | }; |
|
- | 2204 | fixed20_12 memtrbs_r4xx[8] = { |
|
- | 2205 | fixed_init(4), |
|
- | 2206 | fixed_init(5), |
|
- | 2207 | fixed_init(6), |
|
- | 2208 | fixed_init(7), |
|
- | 2209 | fixed_init(8), |
|
- | 2210 | fixed_init(9), |
|
- | 2211 | fixed_init(10), |
|
- | 2212 | fixed_init(11) |
|
- | 2213 | }; |
|
- | 2214 | fixed20_12 min_mem_eff; |
|
- | 2215 | fixed20_12 mc_latency_sclk, mc_latency_mclk, k1; |
|
- | 2216 | fixed20_12 cur_latency_mclk, cur_latency_sclk; |
|
- | 2217 | fixed20_12 disp_latency, disp_latency_overhead, disp_drain_rate, |
|
- | 2218 | disp_drain_rate2, read_return_rate; |
|
- | 2219 | fixed20_12 time_disp1_drop_priority; |
|
- | 2220 | int c; |
|
- | 2221 | int cur_size = 16; /* in octawords */ |
|
- | 2222 | int critical_point = 0, critical_point2; |
|
- | 2223 | /* uint32_t read_return_rate, time_disp1_drop_priority; */ |
|
- | 2224 | int stop_req, max_stop_req; |
|
- | 2225 | struct drm_display_mode *mode1 = NULL; |
|
- | 2226 | struct drm_display_mode *mode2 = NULL; |
|
- | 2227 | uint32_t pixel_bytes1 = 0; |
|
- | 2228 | uint32_t pixel_bytes2 = 0; |
|
- | 2229 | ||
- | 2230 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
|
- | 2231 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
|
- | 2232 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
|
- | 2233 | } |
|
- | 2234 | if (rdev->mode_info.crtcs[1]->base.enabled) { |
|
- | 2235 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
|
- | 2236 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; |
|
- | 2237 | } |
|
- | 2238 | ||
- | 2239 | min_mem_eff.full = rfixed_const_8(0); |
|
- | 2240 | /* get modes */ |
|
- | 2241 | if ((rdev->disp_priority == 2) && ASIC_IS_R300(rdev)) { |
|
- | 2242 | uint32_t mc_init_misc_lat_timer = RREG32(R300_MC_INIT_MISC_LAT_TIMER); |
|
- | 2243 | mc_init_misc_lat_timer &= ~(R300_MC_DISP1R_INIT_LAT_MASK << R300_MC_DISP1R_INIT_LAT_SHIFT); |
|
- | 2244 | mc_init_misc_lat_timer &= ~(R300_MC_DISP0R_INIT_LAT_MASK << R300_MC_DISP0R_INIT_LAT_SHIFT); |
|
- | 2245 | /* check crtc enables */ |
|
- | 2246 | if (mode2) |
|
- | 2247 | mc_init_misc_lat_timer |= (1 << R300_MC_DISP1R_INIT_LAT_SHIFT); |
|
- | 2248 | if (mode1) |
|
- | 2249 | mc_init_misc_lat_timer |= (1 << R300_MC_DISP0R_INIT_LAT_SHIFT); |
|
- | 2250 | WREG32(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer); |
|
- | 2251 | } |
|
- | 2252 | ||
- | 2253 | /* |
|
- | 2254 | * determine is there is enough bw for current mode |
|
- | 2255 | */ |
|
- | 2256 | mclk_ff.full = rfixed_const(rdev->clock.default_mclk); |
|
- | 2257 | temp_ff.full = rfixed_const(100); |
|
- | 2258 | mclk_ff.full = rfixed_div(mclk_ff, temp_ff); |
|
- | 2259 | sclk_ff.full = rfixed_const(rdev->clock.default_sclk); |
|
- | 2260 | sclk_ff.full = rfixed_div(sclk_ff, temp_ff); |
|
- | 2261 | ||
- | 2262 | temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); |
|
- | 2263 | temp_ff.full = rfixed_const(temp); |
|
- | 2264 | mem_bw.full = rfixed_mul(mclk_ff, temp_ff); |
|
- | 2265 | ||
- | 2266 | pix_clk.full = 0; |
|
- | 2267 | pix_clk2.full = 0; |
|
- | 2268 | peak_disp_bw.full = 0; |
|
- | 2269 | if (mode1) { |
|
- | 2270 | temp_ff.full = rfixed_const(1000); |
|
- | 2271 | pix_clk.full = rfixed_const(mode1->clock); /* convert to fixed point */ |
|
- | 2272 | pix_clk.full = rfixed_div(pix_clk, temp_ff); |
|
- | 2273 | temp_ff.full = rfixed_const(pixel_bytes1); |
|
- | 2274 | peak_disp_bw.full += rfixed_mul(pix_clk, temp_ff); |
|
- | 2275 | } |
|
- | 2276 | if (mode2) { |
|
- | 2277 | temp_ff.full = rfixed_const(1000); |
|
- | 2278 | pix_clk2.full = rfixed_const(mode2->clock); /* convert to fixed point */ |
|
- | 2279 | pix_clk2.full = rfixed_div(pix_clk2, temp_ff); |
|
- | 2280 | temp_ff.full = rfixed_const(pixel_bytes2); |
|
- | 2281 | peak_disp_bw.full += rfixed_mul(pix_clk2, temp_ff); |
|
- | 2282 | } |
|
- | 2283 | ||
- | 2284 | mem_bw.full = rfixed_mul(mem_bw, min_mem_eff); |
|
- | 2285 | if (peak_disp_bw.full >= mem_bw.full) { |
|
- | 2286 | DRM_ERROR("You may not have enough display bandwidth for current mode\n" |
|
- | 2287 | "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n"); |
|
- | 2288 | } |
|
- | 2289 | ||
- | 2290 | /* Get values from the EXT_MEM_CNTL register...converting its contents. */ |
|
- | 2291 | temp = RREG32(RADEON_MEM_TIMING_CNTL); |
|
- | 2292 | if ((rdev->family == CHIP_RV100) || (rdev->flags & RADEON_IS_IGP)) { /* RV100, M6, IGPs */ |
|
- | 2293 | mem_trcd = ((temp >> 2) & 0x3) + 1; |
|
- | 2294 | mem_trp = ((temp & 0x3)) + 1; |
|
- | 2295 | mem_tras = ((temp & 0x70) >> 4) + 1; |
|
- | 2296 | } else if (rdev->family == CHIP_R300 || |
|
- | 2297 | rdev->family == CHIP_R350) { /* r300, r350 */ |
|
- | 2298 | mem_trcd = (temp & 0x7) + 1; |
|
- | 2299 | mem_trp = ((temp >> 8) & 0x7) + 1; |
|
- | 2300 | mem_tras = ((temp >> 11) & 0xf) + 4; |
|
- | 2301 | } else if (rdev->family == CHIP_RV350 || |
|
- | 2302 | rdev->family <= CHIP_RV380) { |
|
- | 2303 | /* rv3x0 */ |
|
- | 2304 | mem_trcd = (temp & 0x7) + 3; |
|
- | 2305 | mem_trp = ((temp >> 8) & 0x7) + 3; |
|
- | 2306 | mem_tras = ((temp >> 11) & 0xf) + 6; |
|
- | 2307 | } else if (rdev->family == CHIP_R420 || |
|
- | 2308 | rdev->family == CHIP_R423 || |
|
- | 2309 | rdev->family == CHIP_RV410) { |
|
- | 2310 | /* r4xx */ |
|
- | 2311 | mem_trcd = (temp & 0xf) + 3; |
|
- | 2312 | if (mem_trcd > 15) |
|
- | 2313 | mem_trcd = 15; |
|
- | 2314 | mem_trp = ((temp >> 8) & 0xf) + 3; |
|
- | 2315 | if (mem_trp > 15) |
|
- | 2316 | mem_trp = 15; |
|
- | 2317 | mem_tras = ((temp >> 12) & 0x1f) + 6; |
|
- | 2318 | if (mem_tras > 31) |
|
- | 2319 | mem_tras = 31; |
|
- | 2320 | } else { /* RV200, R200 */ |
|
- | 2321 | mem_trcd = (temp & 0x7) + 1; |
|
- | 2322 | mem_trp = ((temp >> 8) & 0x7) + 1; |
|
- | 2323 | mem_tras = ((temp >> 12) & 0xf) + 4; |
|
- | 2324 | } |
|
- | 2325 | /* convert to FF */ |
|
- | 2326 | trcd_ff.full = rfixed_const(mem_trcd); |
|
- | 2327 | trp_ff.full = rfixed_const(mem_trp); |
|
- | 2328 | tras_ff.full = rfixed_const(mem_tras); |
|
- | 2329 | ||
- | 2330 | /* Get values from the MEM_SDRAM_MODE_REG register...converting its */ |
|
- | 2331 | temp = RREG32(RADEON_MEM_SDRAM_MODE_REG); |
|
- | 2332 | data = (temp & (7 << 20)) >> 20; |
|
- | 2333 | if ((rdev->family == CHIP_RV100) || rdev->flags & RADEON_IS_IGP) { |
|
- | 2334 | if (rdev->family == CHIP_RS480) /* don't think rs400 */ |
|
- | 2335 | tcas_ff = memtcas_rs480_ff[data]; |
|
- | 2336 | else |
|
- | 2337 | tcas_ff = memtcas_ff[data]; |
|
- | 2338 | } else |
|
- | 2339 | tcas_ff = memtcas2_ff[data]; |
|
- | 2340 | ||
- | 2341 | if (rdev->family == CHIP_RS400 || |
|
- | 2342 | rdev->family == CHIP_RS480) { |
|
- | 2343 | /* extra cas latency stored in bits 23-25 0-4 clocks */ |
|
- | 2344 | data = (temp >> 23) & 0x7; |
|
- | 2345 | if (data < 5) |
|
- | 2346 | tcas_ff.full += rfixed_const(data); |
|
- | 2347 | } |
|
- | 2348 | ||
- | 2349 | if (ASIC_IS_R300(rdev) && !(rdev->flags & RADEON_IS_IGP)) { |
|
- | 2350 | /* on the R300, Tcas is included in Trbs. |
|
- | 2351 | */ |
|
- | 2352 | temp = RREG32(RADEON_MEM_CNTL); |
|
- | 2353 | data = (R300_MEM_NUM_CHANNELS_MASK & temp); |
|
- | 2354 | if (data == 1) { |
|
- | 2355 | if (R300_MEM_USE_CD_CH_ONLY & temp) { |
|
- | 2356 | temp = RREG32(R300_MC_IND_INDEX); |
|
- | 2357 | temp &= ~R300_MC_IND_ADDR_MASK; |
|
- | 2358 | temp |= R300_MC_READ_CNTL_CD_mcind; |
|
- | 2359 | WREG32(R300_MC_IND_INDEX, temp); |
|
- | 2360 | temp = RREG32(R300_MC_IND_DATA); |
|
- | 2361 | data = (R300_MEM_RBS_POSITION_C_MASK & temp); |
|
- | 2362 | } else { |
|
- | 2363 | temp = RREG32(R300_MC_READ_CNTL_AB); |
|
- | 2364 | data = (R300_MEM_RBS_POSITION_A_MASK & temp); |
|
- | 2365 | } |
|
- | 2366 | } else { |
|
- | 2367 | temp = RREG32(R300_MC_READ_CNTL_AB); |
|
- | 2368 | data = (R300_MEM_RBS_POSITION_A_MASK & temp); |
|
- | 2369 | } |
|
- | 2370 | if (rdev->family == CHIP_RV410 || |
|
- | 2371 | rdev->family == CHIP_R420 || |
|
- | 2372 | rdev->family == CHIP_R423) |
|
- | 2373 | trbs_ff = memtrbs_r4xx[data]; |
|
- | 2374 | else |
|
- | 2375 | trbs_ff = memtrbs[data]; |
|
- | 2376 | tcas_ff.full += trbs_ff.full; |
|
- | 2377 | } |
|
- | 2378 | ||
- | 2379 | sclk_eff_ff.full = sclk_ff.full; |
|
- | 2380 | ||
- | 2381 | if (rdev->flags & RADEON_IS_AGP) { |
|
- | 2382 | fixed20_12 agpmode_ff; |
|
- | 2383 | agpmode_ff.full = rfixed_const(radeon_agpmode); |
|
- | 2384 | temp_ff.full = rfixed_const_666(16); |
|
- | 2385 | sclk_eff_ff.full -= rfixed_mul(agpmode_ff, temp_ff); |
|
- | 2386 | } |
|
- | 2387 | /* TODO PCIE lanes may affect this - agpmode == 16?? */ |
|
- | 2388 | ||
- | 2389 | if (ASIC_IS_R300(rdev)) { |
|
- | 2390 | sclk_delay_ff.full = rfixed_const(250); |
|
- | 2391 | } else { |
|
- | 2392 | if ((rdev->family == CHIP_RV100) || |
|
- | 2393 | rdev->flags & RADEON_IS_IGP) { |
|
- | 2394 | if (rdev->mc.vram_is_ddr) |
|
- | 2395 | sclk_delay_ff.full = rfixed_const(41); |
|
- | 2396 | else |
|
- | 2397 | sclk_delay_ff.full = rfixed_const(33); |
|
- | 2398 | } else { |
|
- | 2399 | if (rdev->mc.vram_width == 128) |
|
- | 2400 | sclk_delay_ff.full = rfixed_const(57); |
|
- | 2401 | else |
|
- | 2402 | sclk_delay_ff.full = rfixed_const(41); |
|
- | 2403 | } |
|
- | 2404 | } |
|
- | 2405 | ||
- | 2406 | mc_latency_sclk.full = rfixed_div(sclk_delay_ff, sclk_eff_ff); |
|
- | 2407 | ||
- | 2408 | if (rdev->mc.vram_is_ddr) { |
|
- | 2409 | if (rdev->mc.vram_width == 32) { |
|
- | 2410 | k1.full = rfixed_const(40); |
|
- | 2411 | c = 3; |
|
- | 2412 | } else { |
|
- | 2413 | k1.full = rfixed_const(20); |
|
- | 2414 | c = 1; |
|
- | 2415 | } |
|
- | 2416 | } else { |
|
- | 2417 | k1.full = rfixed_const(40); |
|
- | 2418 | c = 3; |
|
- | 2419 | } |
|
- | 2420 | ||
- | 2421 | temp_ff.full = rfixed_const(2); |
|
- | 2422 | mc_latency_mclk.full = rfixed_mul(trcd_ff, temp_ff); |
|
- | 2423 | temp_ff.full = rfixed_const(c); |
|
- | 2424 | mc_latency_mclk.full += rfixed_mul(tcas_ff, temp_ff); |
|
- | 2425 | temp_ff.full = rfixed_const(4); |
|
- | 2426 | mc_latency_mclk.full += rfixed_mul(tras_ff, temp_ff); |
|
- | 2427 | mc_latency_mclk.full += rfixed_mul(trp_ff, temp_ff); |
|
- | 2428 | mc_latency_mclk.full += k1.full; |
|
- | 2429 | ||
- | 2430 | mc_latency_mclk.full = rfixed_div(mc_latency_mclk, mclk_ff); |
|
- | 2431 | mc_latency_mclk.full += rfixed_div(temp_ff, sclk_eff_ff); |
|
- | 2432 | ||
- | 2433 | /* |
|
- | 2434 | HW cursor time assuming worst case of full size colour cursor. |
|
- | 2435 | */ |
|
- | 2436 | temp_ff.full = rfixed_const((2 * (cur_size - (rdev->mc.vram_is_ddr + 1)))); |
|
- | 2437 | temp_ff.full += trcd_ff.full; |
|
- | 2438 | if (temp_ff.full < tras_ff.full) |
|
- | 2439 | temp_ff.full = tras_ff.full; |
|
- | 2440 | cur_latency_mclk.full = rfixed_div(temp_ff, mclk_ff); |
|
- | 2441 | ||
- | 2442 | temp_ff.full = rfixed_const(cur_size); |
|
- | 2443 | cur_latency_sclk.full = rfixed_div(temp_ff, sclk_eff_ff); |
|
- | 2444 | /* |
|
- | 2445 | Find the total latency for the display data. |
|
- | 2446 | */ |
|
- | 2447 | disp_latency_overhead.full = rfixed_const(80); |
|
- | 2448 | disp_latency_overhead.full = rfixed_div(disp_latency_overhead, sclk_ff); |
|
- | 2449 | mc_latency_mclk.full += disp_latency_overhead.full + cur_latency_mclk.full; |
|
- | 2450 | mc_latency_sclk.full += disp_latency_overhead.full + cur_latency_sclk.full; |
|
- | 2451 | ||
- | 2452 | if (mc_latency_mclk.full > mc_latency_sclk.full) |
|
- | 2453 | disp_latency.full = mc_latency_mclk.full; |
|
- | 2454 | else |
|
- | 2455 | disp_latency.full = mc_latency_sclk.full; |
|
- | 2456 | ||
- | 2457 | /* setup Max GRPH_STOP_REQ default value */ |
|
- | 2458 | if (ASIC_IS_RV100(rdev)) |
|
- | 2459 | max_stop_req = 0x5c; |
|
- | 2460 | else |
|
- | 2461 | max_stop_req = 0x7c; |
|
- | 2462 | ||
- | 2463 | if (mode1) { |
|
- | 2464 | /* CRTC1 |
|
- | 2465 | Set GRPH_BUFFER_CNTL register using h/w defined optimal values. |
|
- | 2466 | GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ] |
|
- | 2467 | */ |
|
- | 2468 | stop_req = mode1->hdisplay * pixel_bytes1 / 16; |
|
- | 2469 | ||
- | 2470 | if (stop_req > max_stop_req) |
|
- | 2471 | stop_req = max_stop_req; |
|
- | 2472 | ||
- | 2473 | /* |
|
- | 2474 | Find the drain rate of the display buffer. |
|
- | 2475 | */ |
|
- | 2476 | temp_ff.full = rfixed_const((16/pixel_bytes1)); |
|
- | 2477 | disp_drain_rate.full = rfixed_div(pix_clk, temp_ff); |
|
- | 2478 | ||
- | 2479 | /* |
|
- | 2480 | Find the critical point of the display buffer. |
|
- | 2481 | */ |
|
- | 2482 | crit_point_ff.full = rfixed_mul(disp_drain_rate, disp_latency); |
|
- | 2483 | crit_point_ff.full += rfixed_const_half(0); |
|
- | 2484 | ||
- | 2485 | critical_point = rfixed_trunc(crit_point_ff); |
|
- | 2486 | ||
- | 2487 | if (rdev->disp_priority == 2) { |
|
- | 2488 | critical_point = 0; |
|
- | 2489 | } |
|
- | 2490 | ||
- | 2491 | /* |
|
- | 2492 | The critical point should never be above max_stop_req-4. Setting |
|
- | 2493 | GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time. |
|
- | 2494 | */ |
|
- | 2495 | if (max_stop_req - critical_point < 4) |
|
- | 2496 | critical_point = 0; |
|
- | 2497 | ||
- | 2498 | if (critical_point == 0 && mode2 && rdev->family == CHIP_R300) { |
|
- | 2499 | /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/ |
|
- | 2500 | critical_point = 0x10; |
|
- | 2501 | } |
|
- | 2502 | ||
- | 2503 | temp = RREG32(RADEON_GRPH_BUFFER_CNTL); |
|
- | 2504 | temp &= ~(RADEON_GRPH_STOP_REQ_MASK); |
|
- | 2505 | temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); |
|
- | 2506 | temp &= ~(RADEON_GRPH_START_REQ_MASK); |
|
- | 2507 | if ((rdev->family == CHIP_R350) && |
|
- | 2508 | (stop_req > 0x15)) { |
|
- | 2509 | stop_req -= 0x10; |
|
- | 2510 | } |
|
- | 2511 | temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); |
|
- | 2512 | temp |= RADEON_GRPH_BUFFER_SIZE; |
|
- | 2513 | temp &= ~(RADEON_GRPH_CRITICAL_CNTL | |
|
- | 2514 | RADEON_GRPH_CRITICAL_AT_SOF | |
|
- | 2515 | RADEON_GRPH_STOP_CNTL); |
|
- | 2516 | /* |
|
- | 2517 | Write the result into the register. |
|
- | 2518 | */ |
|
- | 2519 | WREG32(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) | |
|
- | 2520 | (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT))); |
|
- | 2521 | ||
- | 2522 | #if 0 |
|
- | 2523 | if ((rdev->family == CHIP_RS400) || |
|
- | 2524 | (rdev->family == CHIP_RS480)) { |
|
- | 2525 | /* attempt to program RS400 disp regs correctly ??? */ |
|
- | 2526 | temp = RREG32(RS400_DISP1_REG_CNTL); |
|
- | 2527 | temp &= ~(RS400_DISP1_START_REQ_LEVEL_MASK | |
|
- | 2528 | RS400_DISP1_STOP_REQ_LEVEL_MASK); |
|
- | 2529 | WREG32(RS400_DISP1_REQ_CNTL1, (temp | |
|
- | 2530 | (critical_point << RS400_DISP1_START_REQ_LEVEL_SHIFT) | |
|
- | 2531 | (critical_point << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); |
|
- | 2532 | temp = RREG32(RS400_DMIF_MEM_CNTL1); |
|
- | 2533 | temp &= ~(RS400_DISP1_CRITICAL_POINT_START_MASK | |
|
- | 2534 | RS400_DISP1_CRITICAL_POINT_STOP_MASK); |
|
- | 2535 | WREG32(RS400_DMIF_MEM_CNTL1, (temp | |
|
- | 2536 | (critical_point << RS400_DISP1_CRITICAL_POINT_START_SHIFT) | |
|
- | 2537 | (critical_point << RS400_DISP1_CRITICAL_POINT_STOP_SHIFT))); |
|
- | 2538 | } |
|
- | 2539 | #endif |
|
- | 2540 | ||
- | 2541 | DRM_DEBUG("GRPH_BUFFER_CNTL from to %x\n", |
|
- | 2542 | /* (unsigned int)info->SavedReg->grph_buffer_cntl, */ |
|
- | 2543 | (unsigned int)RREG32(RADEON_GRPH_BUFFER_CNTL)); |
|
- | 2544 | } |
|
- | 2545 | ||
- | 2546 | if (mode2) { |
|
- | 2547 | u32 grph2_cntl; |
|
- | 2548 | stop_req = mode2->hdisplay * pixel_bytes2 / 16; |
|
- | 2549 | ||
- | 2550 | if (stop_req > max_stop_req) |
|
- | 2551 | stop_req = max_stop_req; |
|
- | 2552 | ||
- | 2553 | /* |
|
- | 2554 | Find the drain rate of the display buffer. |
|
- | 2555 | */ |
|
- | 2556 | temp_ff.full = rfixed_const((16/pixel_bytes2)); |
|
- | 2557 | disp_drain_rate2.full = rfixed_div(pix_clk2, temp_ff); |
|
- | 2558 | ||
- | 2559 | grph2_cntl = RREG32(RADEON_GRPH2_BUFFER_CNTL); |
|
- | 2560 | grph2_cntl &= ~(RADEON_GRPH_STOP_REQ_MASK); |
|
- | 2561 | grph2_cntl |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT); |
|
- | 2562 | grph2_cntl &= ~(RADEON_GRPH_START_REQ_MASK); |
|
- | 2563 | if ((rdev->family == CHIP_R350) && |
|
- | 2564 | (stop_req > 0x15)) { |
|
- | 2565 | stop_req -= 0x10; |
|
- | 2566 | } |
|
- | 2567 | grph2_cntl |= (stop_req << RADEON_GRPH_START_REQ_SHIFT); |
|
- | 2568 | grph2_cntl |= RADEON_GRPH_BUFFER_SIZE; |
|
- | 2569 | grph2_cntl &= ~(RADEON_GRPH_CRITICAL_CNTL | |
|
- | 2570 | RADEON_GRPH_CRITICAL_AT_SOF | |
|
- | 2571 | RADEON_GRPH_STOP_CNTL); |
|
- | 2572 | ||
- | 2573 | if ((rdev->family == CHIP_RS100) || |
|
- | 2574 | (rdev->family == CHIP_RS200)) |
|
- | 2575 | critical_point2 = 0; |
|
- | 2576 | else { |
|
- | 2577 | temp = (rdev->mc.vram_width * rdev->mc.vram_is_ddr + 1)/128; |
|
- | 2578 | temp_ff.full = rfixed_const(temp); |
|
- | 2579 | temp_ff.full = rfixed_mul(mclk_ff, temp_ff); |
|
- | 2580 | if (sclk_ff.full < temp_ff.full) |
|
- | 2581 | temp_ff.full = sclk_ff.full; |
|
- | 2582 | ||
- | 2583 | read_return_rate.full = temp_ff.full; |
|
- | 2584 | ||
- | 2585 | if (mode1) { |
|
- | 2586 | temp_ff.full = read_return_rate.full - disp_drain_rate.full; |
|
- | 2587 | time_disp1_drop_priority.full = rfixed_div(crit_point_ff, temp_ff); |
|
- | 2588 | } else { |
|
- | 2589 | time_disp1_drop_priority.full = 0; |
|
- | 2590 | } |
|
- | 2591 | crit_point_ff.full = disp_latency.full + time_disp1_drop_priority.full + disp_latency.full; |
|
- | 2592 | crit_point_ff.full = rfixed_mul(crit_point_ff, disp_drain_rate2); |
|
- | 2593 | crit_point_ff.full += rfixed_const_half(0); |
|
- | 2594 | ||
- | 2595 | critical_point2 = rfixed_trunc(crit_point_ff); |
|
- | 2596 | ||
- | 2597 | if (rdev->disp_priority == 2) { |
|
- | 2598 | critical_point2 = 0; |
|
- | 2599 | } |
|
- | 2600 | ||
- | 2601 | if (max_stop_req - critical_point2 < 4) |
|
- | 2602 | critical_point2 = 0; |
|
- | 2603 | ||
- | 2604 | } |
|
- | 2605 | ||
- | 2606 | if (critical_point2 == 0 && rdev->family == CHIP_R300) { |
|
- | 2607 | /* some R300 cards have problem with this set to 0 */ |
|
- | 2608 | critical_point2 = 0x10; |
|
- | 2609 | } |
|
- | 2610 | ||
- | 2611 | WREG32(RADEON_GRPH2_BUFFER_CNTL, ((grph2_cntl & ~RADEON_GRPH_CRITICAL_POINT_MASK) | |
|
- | 2612 | (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT))); |
|
- | 2613 | ||
- | 2614 | if ((rdev->family == CHIP_RS400) || |
|
- | 2615 | (rdev->family == CHIP_RS480)) { |
|
- | 2616 | #if 0 |
|
- | 2617 | /* attempt to program RS400 disp2 regs correctly ??? */ |
|
- | 2618 | temp = RREG32(RS400_DISP2_REQ_CNTL1); |
|
- | 2619 | temp &= ~(RS400_DISP2_START_REQ_LEVEL_MASK | |
|
- | 2620 | RS400_DISP2_STOP_REQ_LEVEL_MASK); |
|
- | 2621 | WREG32(RS400_DISP2_REQ_CNTL1, (temp | |
|
- | 2622 | (critical_point2 << RS400_DISP1_START_REQ_LEVEL_SHIFT) | |
|
- | 2623 | (critical_point2 << RS400_DISP1_STOP_REQ_LEVEL_SHIFT))); |
|
- | 2624 | temp = RREG32(RS400_DISP2_REQ_CNTL2); |
|
- | 2625 | temp &= ~(RS400_DISP2_CRITICAL_POINT_START_MASK | |
|
- | 2626 | RS400_DISP2_CRITICAL_POINT_STOP_MASK); |
|
- | 2627 | WREG32(RS400_DISP2_REQ_CNTL2, (temp | |
|
- | 2628 | (critical_point2 << RS400_DISP2_CRITICAL_POINT_START_SHIFT) | |
|
- | 2629 | (critical_point2 << RS400_DISP2_CRITICAL_POINT_STOP_SHIFT))); |
|
- | 2630 | #endif |
|
- | 2631 | WREG32(RS400_DISP2_REQ_CNTL1, 0x105DC1CC); |
|
- | 2632 | WREG32(RS400_DISP2_REQ_CNTL2, 0x2749D000); |
|
- | 2633 | WREG32(RS400_DMIF_MEM_CNTL1, 0x29CA71DC); |
|
- | 2634 | WREG32(RS400_DISP1_REQ_CNTL1, 0x28FBC3AC); |
|
- | 2635 | } |
|
- | 2636 | ||
- | 2637 | DRM_DEBUG("GRPH2_BUFFER_CNTL from to %x\n", |
|
- | 2638 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
|
- | 2639 | } |
|
- | 2640 | } |
|
- | 2641 | ||
- | 2642 | ||
- | 2643 | ||
- | 2644 | ||
- | 2645 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
|
- | 2646 | { |
|
- | 2647 | /* Shutdown CP we shouldn't need to do that but better be safe than |
|
- | 2648 | * sorry |
|
- | 2649 | */ |
|
- | 2650 | rdev->cp.ready = false; |
|
- | 2651 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
|
- | 2652 | ||
- | 2653 | /* Save few CRTC registers */ |
|
- | 2654 | save->GENMO_WT = RREG32(R_0003C0_GENMO_WT); |
|
- | 2655 | save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); |
|
- | 2656 | save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); |
|
- | 2657 | save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); |
|
- | 2658 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
|
- | 2659 | save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL); |
|
- | 2660 | save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET); |
|
- | 2661 | } |
|
- | 2662 | ||
- | 2663 | /* Disable VGA aperture access */ |
|
- | 2664 | WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT); |
|
- | 2665 | /* Disable cursor, overlay, crtc */ |
|
- | 2666 | WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); |
|
- | 2667 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | |
|
- | 2668 | S_000054_CRTC_DISPLAY_DIS(1)); |
|
- | 2669 | WREG32(R_000050_CRTC_GEN_CNTL, |
|
- | 2670 | (C_000050_CRTC_CUR_EN & save->CRTC_GEN_CNTL) | |
|
- | 2671 | S_000050_CRTC_DISP_REQ_EN_B(1)); |
|
- | 2672 | WREG32(R_000420_OV0_SCALE_CNTL, |
|
- | 2673 | C_000420_OV0_OVERLAY_EN & RREG32(R_000420_OV0_SCALE_CNTL)); |
|
- | 2674 | WREG32(R_000260_CUR_OFFSET, C_000260_CUR_LOCK & save->CUR_OFFSET); |
|
- | 2675 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
|
- | 2676 | WREG32(R_000360_CUR2_OFFSET, save->CUR2_OFFSET | |
|
- | 2677 | S_000360_CUR2_LOCK(1)); |
|
- | 2678 | WREG32(R_0003F8_CRTC2_GEN_CNTL, |
|
- | 2679 | (C_0003F8_CRTC2_CUR_EN & save->CRTC2_GEN_CNTL) | |
|
- | 2680 | S_0003F8_CRTC2_DISPLAY_DIS(1) | |
|
- | 2681 | S_0003F8_CRTC2_DISP_REQ_EN_B(1)); |
|
- | 2682 | WREG32(R_000360_CUR2_OFFSET, |
|
- | 2683 | C_000360_CUR2_LOCK & save->CUR2_OFFSET); |
|
- | 2684 | } |
|
- | 2685 | } |
|
- | 2686 | ||
- | 2687 | void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save) |
|
- | 2688 | { |
|
- | 2689 | /* Update base address for crtc */ |
|
- | 2690 | WREG32(R_00023C_DISPLAY_BASE_ADDR, rdev->mc.vram_location); |
|
- | 2691 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
|
- | 2692 | WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, |
|
- | 2693 | rdev->mc.vram_location); |
|
- | 2694 | } |
|
- | 2695 | /* Restore CRTC registers */ |
|
- | 2696 | WREG32(R_0003C0_GENMO_WT, save->GENMO_WT); |
|
- | 2697 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); |
|
- | 2698 | WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); |
|
- | 2699 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
|
- | 2700 | WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); |
|
- | 2701 | } |
|
- | 2702 | } |
|
- | 2703 | ||
- | 2704 | int drm_order(unsigned long size) |
|
- | 2705 | { |
|
- | 2706 | int order; |
|
- | 2707 | unsigned long tmp; |
|
- | 2708 | ||
- | 2709 | for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ; |
|
- | 2710 | ||
- | 2711 | if (size & (size - 1)) |
|
- | 2712 | ++order; |
|
- | 2713 | ||
- | 2714 | return order; |
|
- | 2715 | }><>><>><>><>><>>>><>><>><>><>><>><>><>><>><>>=>>>><>=>><>><>><>><>=>=>>><>>><>=>><>>=>>>9); |
|
- | 2716 | ><9); |