aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r100.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r--drivers/gpu/drm/radeon/r100.c89
1 files changed, 75 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 8e10aa9f74b0..46da5142b131 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -68,6 +68,56 @@ MODULE_FIRMWARE(FIRMWARE_R520);
68 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 68 * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280
69 */ 69 */
70 70
71void r100_pre_page_flip(struct radeon_device *rdev, int crtc)
72{
73 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc];
74 u32 tmp;
75
76 /* make sure flip is at vb rather than hb */
77 tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset);
78 tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
79 /* make sure pending bit is asserted */
80 tmp |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN;
81 WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp);
82
83 /* set pageflip to happen as late as possible in the vblank interval.
84 * same field for crtc1/2
85 */
86 tmp = RREG32(RADEON_CRTC_GEN_CNTL);
87 tmp &= ~RADEON_CRTC_VSTAT_MODE_MASK;
88 WREG32(RADEON_CRTC_GEN_CNTL, tmp);
89
90 /* enable the pflip int */
91 radeon_irq_kms_pflip_irq_get(rdev, crtc);
92}
93
94void r100_post_page_flip(struct radeon_device *rdev, int crtc)
95{
96 /* disable the pflip int */
97 radeon_irq_kms_pflip_irq_put(rdev, crtc);
98}
99
100u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base)
101{
102 struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
103 u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK;
104
105 /* Lock the graphics update lock */
106 /* update the scanout addresses */
107 WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
108
109 /* Wait for update_pending to go high. */
110 while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET));
111 DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n");
112
113 /* Unlock the lock, so double-buffering can take place inside vblank */
114 tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK;
115 WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp);
116
117 /* Return current update_pending status: */
118 return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET;
119}
120
71void r100_pm_get_dynpm_state(struct radeon_device *rdev) 121void r100_pm_get_dynpm_state(struct radeon_device *rdev)
72{ 122{
73 int i; 123 int i;
@@ -526,10 +576,12 @@ int r100_irq_set(struct radeon_device *rdev)
526 if (rdev->irq.gui_idle) { 576 if (rdev->irq.gui_idle) {
527 tmp |= RADEON_GUI_IDLE_MASK; 577 tmp |= RADEON_GUI_IDLE_MASK;
528 } 578 }
529 if (rdev->irq.crtc_vblank_int[0]) { 579 if (rdev->irq.crtc_vblank_int[0] ||
580 rdev->irq.pflip[0]) {
530 tmp |= RADEON_CRTC_VBLANK_MASK; 581 tmp |= RADEON_CRTC_VBLANK_MASK;
531 } 582 }
532 if (rdev->irq.crtc_vblank_int[1]) { 583 if (rdev->irq.crtc_vblank_int[1] ||
584 rdev->irq.pflip[1]) {
533 tmp |= RADEON_CRTC2_VBLANK_MASK; 585 tmp |= RADEON_CRTC2_VBLANK_MASK;
534 } 586 }
535 if (rdev->irq.hpd[0]) { 587 if (rdev->irq.hpd[0]) {
@@ -600,14 +652,22 @@ int r100_irq_process(struct radeon_device *rdev)
600 } 652 }
601 /* Vertical blank interrupts */ 653 /* Vertical blank interrupts */
602 if (status & RADEON_CRTC_VBLANK_STAT) { 654 if (status & RADEON_CRTC_VBLANK_STAT) {
603 drm_handle_vblank(rdev->ddev, 0); 655 if (rdev->irq.crtc_vblank_int[0]) {
604 rdev->pm.vblank_sync = true; 656 drm_handle_vblank(rdev->ddev, 0);
605 wake_up(&rdev->irq.vblank_queue); 657 rdev->pm.vblank_sync = true;
658 wake_up(&rdev->irq.vblank_queue);
659 }
660 if (rdev->irq.pflip[0])
661 radeon_crtc_handle_flip(rdev, 0);
606 } 662 }
607 if (status & RADEON_CRTC2_VBLANK_STAT) { 663 if (status & RADEON_CRTC2_VBLANK_STAT) {
608 drm_handle_vblank(rdev->ddev, 1); 664 if (rdev->irq.crtc_vblank_int[1]) {
609 rdev->pm.vblank_sync = true; 665 drm_handle_vblank(rdev->ddev, 1);
610 wake_up(&rdev->irq.vblank_queue); 666 rdev->pm.vblank_sync = true;
667 wake_up(&rdev->irq.vblank_queue);
668 }
669 if (rdev->irq.pflip[1])
670 radeon_crtc_handle_flip(rdev, 1);
611 } 671 }
612 if (status & RADEON_FP_DETECT_STAT) { 672 if (status & RADEON_FP_DETECT_STAT) {
613 queue_hotplug = true; 673 queue_hotplug = true;
@@ -622,7 +682,7 @@ int r100_irq_process(struct radeon_device *rdev)
622 /* reset gui idle ack. the status bit is broken */ 682 /* reset gui idle ack. the status bit is broken */
623 rdev->irq.gui_idle_acked = false; 683 rdev->irq.gui_idle_acked = false;
624 if (queue_hotplug) 684 if (queue_hotplug)
625 queue_work(rdev->wq, &rdev->hotplug_work); 685 schedule_work(&rdev->hotplug_work);
626 if (rdev->msi_enabled) { 686 if (rdev->msi_enabled) {
627 switch (rdev->family) { 687 switch (rdev->family) {
628 case CHIP_RS400: 688 case CHIP_RS400:
@@ -2026,12 +2086,13 @@ int r100_asic_reset(struct radeon_device *rdev)
2026{ 2086{
2027 struct r100_mc_save save; 2087 struct r100_mc_save save;
2028 u32 status, tmp; 2088 u32 status, tmp;
2089 int ret = 0;
2029 2090
2030 r100_mc_stop(rdev, &save);
2031 status = RREG32(R_000E40_RBBM_STATUS); 2091 status = RREG32(R_000E40_RBBM_STATUS);
2032 if (!G_000E40_GUI_ACTIVE(status)) { 2092 if (!G_000E40_GUI_ACTIVE(status)) {
2033 return 0; 2093 return 0;
2034 } 2094 }
2095 r100_mc_stop(rdev, &save);
2035 status = RREG32(R_000E40_RBBM_STATUS); 2096 status = RREG32(R_000E40_RBBM_STATUS);
2036 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status); 2097 dev_info(rdev->dev, "(%s:%d) RBBM_STATUS=0x%08X\n", __func__, __LINE__, status);
2037 /* stop CP */ 2098 /* stop CP */
@@ -2071,11 +2132,11 @@ int r100_asic_reset(struct radeon_device *rdev)
2071 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { 2132 G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) {
2072 dev_err(rdev->dev, "failed to reset GPU\n"); 2133 dev_err(rdev->dev, "failed to reset GPU\n");
2073 rdev->gpu_lockup = true; 2134 rdev->gpu_lockup = true;
2074 return -1; 2135 ret = -1;
2075 } 2136 } else
2137 dev_info(rdev->dev, "GPU reset succeed\n");
2076 r100_mc_resume(rdev, &save); 2138 r100_mc_resume(rdev, &save);
2077 dev_info(rdev->dev, "GPU reset succeed\n"); 2139 return ret;
2078 return 0;
2079} 2140}
2080 2141
2081void r100_set_common_regs(struct radeon_device *rdev) 2142void r100_set_common_regs(struct radeon_device *rdev)