aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r--drivers/gpu/drm/radeon/r600.c126
1 files changed, 71 insertions, 55 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a3552594ccc4..15b95724c408 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2863,6 +2863,8 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)
2863 WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 2863 WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
2864 WREG32(GRBM_INT_CNTL, 0); 2864 WREG32(GRBM_INT_CNTL, 0);
2865 WREG32(DxMODE_INT_MASK, 0); 2865 WREG32(DxMODE_INT_MASK, 0);
2866 WREG32(D1GRPH_INTERRUPT_CONTROL, 0);
2867 WREG32(D2GRPH_INTERRUPT_CONTROL, 0);
2866 if (ASIC_IS_DCE3(rdev)) { 2868 if (ASIC_IS_DCE3(rdev)) {
2867 WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); 2869 WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
2868 WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); 2870 WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
@@ -2987,6 +2989,7 @@ int r600_irq_set(struct radeon_device *rdev)
2987 u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; 2989 u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
2988 u32 grbm_int_cntl = 0; 2990 u32 grbm_int_cntl = 0;
2989 u32 hdmi1, hdmi2; 2991 u32 hdmi1, hdmi2;
2992 u32 d1grph = 0, d2grph = 0;
2990 2993
2991 if (!rdev->irq.installed) { 2994 if (!rdev->irq.installed) {
2992 WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 2995 WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
@@ -3023,11 +3026,13 @@ int r600_irq_set(struct radeon_device *rdev)
3023 cp_int_cntl |= RB_INT_ENABLE; 3026 cp_int_cntl |= RB_INT_ENABLE;
3024 cp_int_cntl |= TIME_STAMP_INT_ENABLE; 3027 cp_int_cntl |= TIME_STAMP_INT_ENABLE;
3025 } 3028 }
3026 if (rdev->irq.crtc_vblank_int[0]) { 3029 if (rdev->irq.crtc_vblank_int[0] ||
3030 rdev->irq.pflip[0]) {
3027 DRM_DEBUG("r600_irq_set: vblank 0\n"); 3031 DRM_DEBUG("r600_irq_set: vblank 0\n");
3028 mode_int |= D1MODE_VBLANK_INT_MASK; 3032 mode_int |= D1MODE_VBLANK_INT_MASK;
3029 } 3033 }
3030 if (rdev->irq.crtc_vblank_int[1]) { 3034 if (rdev->irq.crtc_vblank_int[1] ||
3035 rdev->irq.pflip[1]) {
3031 DRM_DEBUG("r600_irq_set: vblank 1\n"); 3036 DRM_DEBUG("r600_irq_set: vblank 1\n");
3032 mode_int |= D2MODE_VBLANK_INT_MASK; 3037 mode_int |= D2MODE_VBLANK_INT_MASK;
3033 } 3038 }
@@ -3070,6 +3075,8 @@ int r600_irq_set(struct radeon_device *rdev)
3070 3075
3071 WREG32(CP_INT_CNTL, cp_int_cntl); 3076 WREG32(CP_INT_CNTL, cp_int_cntl);
3072 WREG32(DxMODE_INT_MASK, mode_int); 3077 WREG32(DxMODE_INT_MASK, mode_int);
3078 WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph);
3079 WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph);
3073 WREG32(GRBM_INT_CNTL, grbm_int_cntl); 3080 WREG32(GRBM_INT_CNTL, grbm_int_cntl);
3074 WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); 3081 WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1);
3075 if (ASIC_IS_DCE3(rdev)) { 3082 if (ASIC_IS_DCE3(rdev)) {
@@ -3092,32 +3099,35 @@ int r600_irq_set(struct radeon_device *rdev)
3092 return 0; 3099 return 0;
3093} 3100}
3094 3101
3095static inline void r600_irq_ack(struct radeon_device *rdev, 3102static inline void r600_irq_ack(struct radeon_device *rdev)
3096 u32 *disp_int,
3097 u32 *disp_int_cont,
3098 u32 *disp_int_cont2)
3099{ 3103{
3100 u32 tmp; 3104 u32 tmp;
3101 3105
3102 if (ASIC_IS_DCE3(rdev)) { 3106 if (ASIC_IS_DCE3(rdev)) {
3103 *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); 3107 rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
3104 *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); 3108 rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
3105 *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); 3109 rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
3106 } else { 3110 } else {
3107 *disp_int = RREG32(DISP_INTERRUPT_STATUS); 3111 rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS);
3108 *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); 3112 rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
3109 *disp_int_cont2 = 0; 3113 rdev->irq.stat_regs.r600.disp_int_cont2 = 0;
3110 } 3114 }
3111 3115 rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS);
3112 if (*disp_int & LB_D1_VBLANK_INTERRUPT) 3116 rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS);
3117
3118 if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED)
3119 WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
3120 if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED)
3121 WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
3122 if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT)
3113 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); 3123 WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
3114 if (*disp_int & LB_D1_VLINE_INTERRUPT) 3124 if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT)
3115 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); 3125 WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
3116 if (*disp_int & LB_D2_VBLANK_INTERRUPT) 3126 if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT)
3117 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); 3127 WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
3118 if (*disp_int & LB_D2_VLINE_INTERRUPT) 3128 if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT)
3119 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); 3129 WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
3120 if (*disp_int & DC_HPD1_INTERRUPT) { 3130 if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
3121 if (ASIC_IS_DCE3(rdev)) { 3131 if (ASIC_IS_DCE3(rdev)) {
3122 tmp = RREG32(DC_HPD1_INT_CONTROL); 3132 tmp = RREG32(DC_HPD1_INT_CONTROL);
3123 tmp |= DC_HPDx_INT_ACK; 3133 tmp |= DC_HPDx_INT_ACK;
@@ -3128,7 +3138,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev,
3128 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); 3138 WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
3129 } 3139 }
3130 } 3140 }
3131 if (*disp_int & DC_HPD2_INTERRUPT) { 3141 if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
3132 if (ASIC_IS_DCE3(rdev)) { 3142 if (ASIC_IS_DCE3(rdev)) {
3133 tmp = RREG32(DC_HPD2_INT_CONTROL); 3143 tmp = RREG32(DC_HPD2_INT_CONTROL);
3134 tmp |= DC_HPDx_INT_ACK; 3144 tmp |= DC_HPDx_INT_ACK;
@@ -3139,7 +3149,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev,
3139 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); 3149 WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
3140 } 3150 }
3141 } 3151 }
3142 if (*disp_int_cont & DC_HPD3_INTERRUPT) { 3152 if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
3143 if (ASIC_IS_DCE3(rdev)) { 3153 if (ASIC_IS_DCE3(rdev)) {
3144 tmp = RREG32(DC_HPD3_INT_CONTROL); 3154 tmp = RREG32(DC_HPD3_INT_CONTROL);
3145 tmp |= DC_HPDx_INT_ACK; 3155 tmp |= DC_HPDx_INT_ACK;
@@ -3150,18 +3160,18 @@ static inline void r600_irq_ack(struct radeon_device *rdev,
3150 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); 3160 WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
3151 } 3161 }
3152 } 3162 }
3153 if (*disp_int_cont & DC_HPD4_INTERRUPT) { 3163 if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
3154 tmp = RREG32(DC_HPD4_INT_CONTROL); 3164 tmp = RREG32(DC_HPD4_INT_CONTROL);
3155 tmp |= DC_HPDx_INT_ACK; 3165 tmp |= DC_HPDx_INT_ACK;
3156 WREG32(DC_HPD4_INT_CONTROL, tmp); 3166 WREG32(DC_HPD4_INT_CONTROL, tmp);
3157 } 3167 }
3158 if (ASIC_IS_DCE32(rdev)) { 3168 if (ASIC_IS_DCE32(rdev)) {
3159 if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { 3169 if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
3160 tmp = RREG32(DC_HPD5_INT_CONTROL); 3170 tmp = RREG32(DC_HPD5_INT_CONTROL);
3161 tmp |= DC_HPDx_INT_ACK; 3171 tmp |= DC_HPDx_INT_ACK;
3162 WREG32(DC_HPD5_INT_CONTROL, tmp); 3172 WREG32(DC_HPD5_INT_CONTROL, tmp);
3163 } 3173 }
3164 if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { 3174 if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
3165 tmp = RREG32(DC_HPD5_INT_CONTROL); 3175 tmp = RREG32(DC_HPD5_INT_CONTROL);
3166 tmp |= DC_HPDx_INT_ACK; 3176 tmp |= DC_HPDx_INT_ACK;
3167 WREG32(DC_HPD6_INT_CONTROL, tmp); 3177 WREG32(DC_HPD6_INT_CONTROL, tmp);
@@ -3183,12 +3193,10 @@ static inline void r600_irq_ack(struct radeon_device *rdev,
3183 3193
3184void r600_irq_disable(struct radeon_device *rdev) 3194void r600_irq_disable(struct radeon_device *rdev)
3185{ 3195{
3186 u32 disp_int, disp_int_cont, disp_int_cont2;
3187
3188 r600_disable_interrupts(rdev); 3196 r600_disable_interrupts(rdev);
3189 /* Wait and acknowledge irq */ 3197 /* Wait and acknowledge irq */
3190 mdelay(1); 3198 mdelay(1);
3191 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); 3199 r600_irq_ack(rdev);
3192 r600_disable_interrupt_state(rdev); 3200 r600_disable_interrupt_state(rdev);
3193} 3201}
3194 3202
@@ -3251,7 +3259,7 @@ int r600_irq_process(struct radeon_device *rdev)
3251 u32 wptr = r600_get_ih_wptr(rdev); 3259 u32 wptr = r600_get_ih_wptr(rdev);
3252 u32 rptr = rdev->ih.rptr; 3260 u32 rptr = rdev->ih.rptr;
3253 u32 src_id, src_data; 3261 u32 src_id, src_data;
3254 u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; 3262 u32 ring_index;
3255 unsigned long flags; 3263 unsigned long flags;
3256 bool queue_hotplug = false; 3264 bool queue_hotplug = false;
3257 3265
@@ -3272,7 +3280,7 @@ int r600_irq_process(struct radeon_device *rdev)
3272 3280
3273restart_ih: 3281restart_ih:
3274 /* display interrupts */ 3282 /* display interrupts */
3275 r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); 3283 r600_irq_ack(rdev);
3276 3284
3277 rdev->ih.wptr = wptr; 3285 rdev->ih.wptr = wptr;
3278 while (rptr != wptr) { 3286 while (rptr != wptr) {
@@ -3285,17 +3293,21 @@ restart_ih:
3285 case 1: /* D1 vblank/vline */ 3293 case 1: /* D1 vblank/vline */
3286 switch (src_data) { 3294 switch (src_data) {
3287 case 0: /* D1 vblank */ 3295 case 0: /* D1 vblank */
3288 if (disp_int & LB_D1_VBLANK_INTERRUPT) { 3296 if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) {
3289 drm_handle_vblank(rdev->ddev, 0); 3297 if (rdev->irq.pflip[0])
3290 rdev->pm.vblank_sync = true; 3298 radeon_crtc_handle_flip(rdev, 0);
3291 wake_up(&rdev->irq.vblank_queue); 3299 if (rdev->irq.crtc_vblank_int[0]) {
3292 disp_int &= ~LB_D1_VBLANK_INTERRUPT; 3300 drm_handle_vblank(rdev->ddev, 0);
3301 rdev->pm.vblank_sync = true;
3302 wake_up(&rdev->irq.vblank_queue);
3303 }
3304 rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
3293 DRM_DEBUG("IH: D1 vblank\n"); 3305 DRM_DEBUG("IH: D1 vblank\n");
3294 } 3306 }
3295 break; 3307 break;
3296 case 1: /* D1 vline */ 3308 case 1: /* D1 vline */
3297 if (disp_int & LB_D1_VLINE_INTERRUPT) { 3309 if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) {
3298 disp_int &= ~LB_D1_VLINE_INTERRUPT; 3310 rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
3299 DRM_DEBUG("IH: D1 vline\n"); 3311 DRM_DEBUG("IH: D1 vline\n");
3300 } 3312 }
3301 break; 3313 break;
@@ -3307,17 +3319,21 @@ restart_ih:
3307 case 5: /* D2 vblank/vline */ 3319 case 5: /* D2 vblank/vline */
3308 switch (src_data) { 3320 switch (src_data) {
3309 case 0: /* D2 vblank */ 3321 case 0: /* D2 vblank */
3310 if (disp_int & LB_D2_VBLANK_INTERRUPT) { 3322 if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) {
3311 drm_handle_vblank(rdev->ddev, 1); 3323 if (rdev->irq.pflip[1])
3312 rdev->pm.vblank_sync = true; 3324 radeon_crtc_handle_flip(rdev, 1);
3313 wake_up(&rdev->irq.vblank_queue); 3325 if (rdev->irq.crtc_vblank_int[1]) {
3314 disp_int &= ~LB_D2_VBLANK_INTERRUPT; 3326 drm_handle_vblank(rdev->ddev, 1);
3327 rdev->pm.vblank_sync = true;
3328 wake_up(&rdev->irq.vblank_queue);
3329 }
3330 rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
3315 DRM_DEBUG("IH: D2 vblank\n"); 3331 DRM_DEBUG("IH: D2 vblank\n");
3316 } 3332 }
3317 break; 3333 break;
3318 case 1: /* D1 vline */ 3334 case 1: /* D1 vline */
3319 if (disp_int & LB_D2_VLINE_INTERRUPT) { 3335 if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) {
3320 disp_int &= ~LB_D2_VLINE_INTERRUPT; 3336 rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
3321 DRM_DEBUG("IH: D2 vline\n"); 3337 DRM_DEBUG("IH: D2 vline\n");
3322 } 3338 }
3323 break; 3339 break;
@@ -3329,43 +3345,43 @@ restart_ih:
3329 case 19: /* HPD/DAC hotplug */ 3345 case 19: /* HPD/DAC hotplug */
3330 switch (src_data) { 3346 switch (src_data) {
3331 case 0: 3347 case 0:
3332 if (disp_int & DC_HPD1_INTERRUPT) { 3348 if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
3333 disp_int &= ~DC_HPD1_INTERRUPT; 3349 rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
3334 queue_hotplug = true; 3350 queue_hotplug = true;
3335 DRM_DEBUG("IH: HPD1\n"); 3351 DRM_DEBUG("IH: HPD1\n");
3336 } 3352 }
3337 break; 3353 break;
3338 case 1: 3354 case 1:
3339 if (disp_int & DC_HPD2_INTERRUPT) { 3355 if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
3340 disp_int &= ~DC_HPD2_INTERRUPT; 3356 rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
3341 queue_hotplug = true; 3357 queue_hotplug = true;
3342 DRM_DEBUG("IH: HPD2\n"); 3358 DRM_DEBUG("IH: HPD2\n");
3343 } 3359 }
3344 break; 3360 break;
3345 case 4: 3361 case 4:
3346 if (disp_int_cont & DC_HPD3_INTERRUPT) { 3362 if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
3347 disp_int_cont &= ~DC_HPD3_INTERRUPT; 3363 rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
3348 queue_hotplug = true; 3364 queue_hotplug = true;
3349 DRM_DEBUG("IH: HPD3\n"); 3365 DRM_DEBUG("IH: HPD3\n");
3350 } 3366 }
3351 break; 3367 break;
3352 case 5: 3368 case 5:
3353 if (disp_int_cont & DC_HPD4_INTERRUPT) { 3369 if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
3354 disp_int_cont &= ~DC_HPD4_INTERRUPT; 3370 rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
3355 queue_hotplug = true; 3371 queue_hotplug = true;
3356 DRM_DEBUG("IH: HPD4\n"); 3372 DRM_DEBUG("IH: HPD4\n");
3357 } 3373 }
3358 break; 3374 break;
3359 case 10: 3375 case 10:
3360 if (disp_int_cont2 & DC_HPD5_INTERRUPT) { 3376 if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
3361 disp_int_cont2 &= ~DC_HPD5_INTERRUPT; 3377 rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
3362 queue_hotplug = true; 3378 queue_hotplug = true;
3363 DRM_DEBUG("IH: HPD5\n"); 3379 DRM_DEBUG("IH: HPD5\n");
3364 } 3380 }
3365 break; 3381 break;
3366 case 12: 3382 case 12:
3367 if (disp_int_cont2 & DC_HPD6_INTERRUPT) { 3383 if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
3368 disp_int_cont2 &= ~DC_HPD6_INTERRUPT; 3384 rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
3369 queue_hotplug = true; 3385 queue_hotplug = true;
3370 DRM_DEBUG("IH: HPD6\n"); 3386 DRM_DEBUG("IH: HPD6\n");
3371 } 3387 }