diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 357 |
1 files changed, 300 insertions, 57 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 9c92db7c896b..6b50716267c0 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -83,6 +83,9 @@ MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); | |||
83 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); | 83 | MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); |
84 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); | 84 | MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); |
85 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); | 85 | MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); |
86 | MODULE_FIRMWARE("radeon/PALM_pfp.bin"); | ||
87 | MODULE_FIRMWARE("radeon/PALM_me.bin"); | ||
88 | MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); | ||
86 | 89 | ||
87 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | 90 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); |
88 | 91 | ||
@@ -91,6 +94,7 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
91 | void r600_gpu_init(struct radeon_device *rdev); | 94 | void r600_gpu_init(struct radeon_device *rdev); |
92 | void r600_fini(struct radeon_device *rdev); | 95 | void r600_fini(struct radeon_device *rdev); |
93 | void r600_irq_disable(struct radeon_device *rdev); | 96 | void r600_irq_disable(struct radeon_device *rdev); |
97 | static void r600_pcie_gen2_enable(struct radeon_device *rdev); | ||
94 | 98 | ||
95 | /* get temperature in millidegrees */ | 99 | /* get temperature in millidegrees */ |
96 | u32 rv6xx_get_temp(struct radeon_device *rdev) | 100 | u32 rv6xx_get_temp(struct radeon_device *rdev) |
@@ -1164,7 +1168,7 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
1164 | * Note: GTT start, end, size should be initialized before calling this | 1168 | * Note: GTT start, end, size should be initialized before calling this |
1165 | * function on AGP platform. | 1169 | * function on AGP platform. |
1166 | */ | 1170 | */ |
1167 | void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | 1171 | static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) |
1168 | { | 1172 | { |
1169 | u64 size_bf, size_af; | 1173 | u64 size_bf, size_af; |
1170 | 1174 | ||
@@ -2009,6 +2013,10 @@ int r600_init_microcode(struct radeon_device *rdev) | |||
2009 | chip_name = "CYPRESS"; | 2013 | chip_name = "CYPRESS"; |
2010 | rlc_chip_name = "CYPRESS"; | 2014 | rlc_chip_name = "CYPRESS"; |
2011 | break; | 2015 | break; |
2016 | case CHIP_PALM: | ||
2017 | chip_name = "PALM"; | ||
2018 | rlc_chip_name = "SUMO"; | ||
2019 | break; | ||
2012 | default: BUG(); | 2020 | default: BUG(); |
2013 | } | 2021 | } |
2014 | 2022 | ||
@@ -2372,6 +2380,9 @@ int r600_startup(struct radeon_device *rdev) | |||
2372 | { | 2380 | { |
2373 | int r; | 2381 | int r; |
2374 | 2382 | ||
2383 | /* enable pcie gen2 link */ | ||
2384 | r600_pcie_gen2_enable(rdev); | ||
2385 | |||
2375 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | 2386 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { |
2376 | r = r600_init_microcode(rdev); | 2387 | r = r600_init_microcode(rdev); |
2377 | if (r) { | 2388 | if (r) { |
@@ -2874,6 +2885,8 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) | |||
2874 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); | 2885 | WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); |
2875 | WREG32(GRBM_INT_CNTL, 0); | 2886 | WREG32(GRBM_INT_CNTL, 0); |
2876 | WREG32(DxMODE_INT_MASK, 0); | 2887 | WREG32(DxMODE_INT_MASK, 0); |
2888 | WREG32(D1GRPH_INTERRUPT_CONTROL, 0); | ||
2889 | WREG32(D2GRPH_INTERRUPT_CONTROL, 0); | ||
2877 | if (ASIC_IS_DCE3(rdev)) { | 2890 | if (ASIC_IS_DCE3(rdev)) { |
2878 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | 2891 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); |
2879 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | 2892 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); |
@@ -2998,6 +3011,7 @@ int r600_irq_set(struct radeon_device *rdev) | |||
2998 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 3011 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
2999 | u32 grbm_int_cntl = 0; | 3012 | u32 grbm_int_cntl = 0; |
3000 | u32 hdmi1, hdmi2; | 3013 | u32 hdmi1, hdmi2; |
3014 | u32 d1grph = 0, d2grph = 0; | ||
3001 | 3015 | ||
3002 | if (!rdev->irq.installed) { | 3016 | if (!rdev->irq.installed) { |
3003 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); | 3017 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
@@ -3034,11 +3048,13 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3034 | cp_int_cntl |= RB_INT_ENABLE; | 3048 | cp_int_cntl |= RB_INT_ENABLE; |
3035 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; | 3049 | cp_int_cntl |= TIME_STAMP_INT_ENABLE; |
3036 | } | 3050 | } |
3037 | if (rdev->irq.crtc_vblank_int[0]) { | 3051 | if (rdev->irq.crtc_vblank_int[0] || |
3052 | rdev->irq.pflip[0]) { | ||
3038 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | 3053 | DRM_DEBUG("r600_irq_set: vblank 0\n"); |
3039 | mode_int |= D1MODE_VBLANK_INT_MASK; | 3054 | mode_int |= D1MODE_VBLANK_INT_MASK; |
3040 | } | 3055 | } |
3041 | if (rdev->irq.crtc_vblank_int[1]) { | 3056 | if (rdev->irq.crtc_vblank_int[1] || |
3057 | rdev->irq.pflip[1]) { | ||
3042 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | 3058 | DRM_DEBUG("r600_irq_set: vblank 1\n"); |
3043 | mode_int |= D2MODE_VBLANK_INT_MASK; | 3059 | mode_int |= D2MODE_VBLANK_INT_MASK; |
3044 | } | 3060 | } |
@@ -3081,6 +3097,8 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3081 | 3097 | ||
3082 | WREG32(CP_INT_CNTL, cp_int_cntl); | 3098 | WREG32(CP_INT_CNTL, cp_int_cntl); |
3083 | WREG32(DxMODE_INT_MASK, mode_int); | 3099 | WREG32(DxMODE_INT_MASK, mode_int); |
3100 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); | ||
3101 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); | ||
3084 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3102 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
3085 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); | 3103 | WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); |
3086 | if (ASIC_IS_DCE3(rdev)) { | 3104 | if (ASIC_IS_DCE3(rdev)) { |
@@ -3103,32 +3121,35 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3103 | return 0; | 3121 | return 0; |
3104 | } | 3122 | } |
3105 | 3123 | ||
3106 | static inline void r600_irq_ack(struct radeon_device *rdev, | 3124 | static inline void r600_irq_ack(struct radeon_device *rdev) |
3107 | u32 *disp_int, | ||
3108 | u32 *disp_int_cont, | ||
3109 | u32 *disp_int_cont2) | ||
3110 | { | 3125 | { |
3111 | u32 tmp; | 3126 | u32 tmp; |
3112 | 3127 | ||
3113 | if (ASIC_IS_DCE3(rdev)) { | 3128 | if (ASIC_IS_DCE3(rdev)) { |
3114 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | 3129 | rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); |
3115 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | 3130 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); |
3116 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | 3131 | rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); |
3117 | } else { | 3132 | } else { |
3118 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | 3133 | rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); |
3119 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | 3134 | rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); |
3120 | *disp_int_cont2 = 0; | 3135 | rdev->irq.stat_regs.r600.disp_int_cont2 = 0; |
3121 | } | 3136 | } |
3122 | 3137 | rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); | |
3123 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | 3138 | rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); |
3139 | |||
3140 | if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
3141 | WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
3142 | if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) | ||
3143 | WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); | ||
3144 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) | ||
3124 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3145 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
3125 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | 3146 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) |
3126 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3147 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
3127 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) | 3148 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) |
3128 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | 3149 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); |
3129 | if (*disp_int & LB_D2_VLINE_INTERRUPT) | 3150 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) |
3130 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | 3151 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); |
3131 | if (*disp_int & DC_HPD1_INTERRUPT) { | 3152 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
3132 | if (ASIC_IS_DCE3(rdev)) { | 3153 | if (ASIC_IS_DCE3(rdev)) { |
3133 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 3154 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
3134 | tmp |= DC_HPDx_INT_ACK; | 3155 | tmp |= DC_HPDx_INT_ACK; |
@@ -3139,7 +3160,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3139 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | 3160 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); |
3140 | } | 3161 | } |
3141 | } | 3162 | } |
3142 | if (*disp_int & DC_HPD2_INTERRUPT) { | 3163 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
3143 | if (ASIC_IS_DCE3(rdev)) { | 3164 | if (ASIC_IS_DCE3(rdev)) { |
3144 | tmp = RREG32(DC_HPD2_INT_CONTROL); | 3165 | tmp = RREG32(DC_HPD2_INT_CONTROL); |
3145 | tmp |= DC_HPDx_INT_ACK; | 3166 | tmp |= DC_HPDx_INT_ACK; |
@@ -3150,7 +3171,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3150 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | 3171 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); |
3151 | } | 3172 | } |
3152 | } | 3173 | } |
3153 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | 3174 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
3154 | if (ASIC_IS_DCE3(rdev)) { | 3175 | if (ASIC_IS_DCE3(rdev)) { |
3155 | tmp = RREG32(DC_HPD3_INT_CONTROL); | 3176 | tmp = RREG32(DC_HPD3_INT_CONTROL); |
3156 | tmp |= DC_HPDx_INT_ACK; | 3177 | tmp |= DC_HPDx_INT_ACK; |
@@ -3161,18 +3182,18 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3161 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | 3182 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); |
3162 | } | 3183 | } |
3163 | } | 3184 | } |
3164 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | 3185 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
3165 | tmp = RREG32(DC_HPD4_INT_CONTROL); | 3186 | tmp = RREG32(DC_HPD4_INT_CONTROL); |
3166 | tmp |= DC_HPDx_INT_ACK; | 3187 | tmp |= DC_HPDx_INT_ACK; |
3167 | WREG32(DC_HPD4_INT_CONTROL, tmp); | 3188 | WREG32(DC_HPD4_INT_CONTROL, tmp); |
3168 | } | 3189 | } |
3169 | if (ASIC_IS_DCE32(rdev)) { | 3190 | if (ASIC_IS_DCE32(rdev)) { |
3170 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3191 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
3171 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3192 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
3172 | tmp |= DC_HPDx_INT_ACK; | 3193 | tmp |= DC_HPDx_INT_ACK; |
3173 | WREG32(DC_HPD5_INT_CONTROL, tmp); | 3194 | WREG32(DC_HPD5_INT_CONTROL, tmp); |
3174 | } | 3195 | } |
3175 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3196 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
3176 | tmp = RREG32(DC_HPD5_INT_CONTROL); | 3197 | tmp = RREG32(DC_HPD5_INT_CONTROL); |
3177 | tmp |= DC_HPDx_INT_ACK; | 3198 | tmp |= DC_HPDx_INT_ACK; |
3178 | WREG32(DC_HPD6_INT_CONTROL, tmp); | 3199 | WREG32(DC_HPD6_INT_CONTROL, tmp); |
@@ -3194,12 +3215,10 @@ static inline void r600_irq_ack(struct radeon_device *rdev, | |||
3194 | 3215 | ||
3195 | void r600_irq_disable(struct radeon_device *rdev) | 3216 | void r600_irq_disable(struct radeon_device *rdev) |
3196 | { | 3217 | { |
3197 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
3198 | |||
3199 | r600_disable_interrupts(rdev); | 3218 | r600_disable_interrupts(rdev); |
3200 | /* Wait and acknowledge irq */ | 3219 | /* Wait and acknowledge irq */ |
3201 | mdelay(1); | 3220 | mdelay(1); |
3202 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3221 | r600_irq_ack(rdev); |
3203 | r600_disable_interrupt_state(rdev); | 3222 | r600_disable_interrupt_state(rdev); |
3204 | } | 3223 | } |
3205 | 3224 | ||
@@ -3262,7 +3281,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3262 | u32 wptr = r600_get_ih_wptr(rdev); | 3281 | u32 wptr = r600_get_ih_wptr(rdev); |
3263 | u32 rptr = rdev->ih.rptr; | 3282 | u32 rptr = rdev->ih.rptr; |
3264 | u32 src_id, src_data; | 3283 | u32 src_id, src_data; |
3265 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | 3284 | u32 ring_index; |
3266 | unsigned long flags; | 3285 | unsigned long flags; |
3267 | bool queue_hotplug = false; | 3286 | bool queue_hotplug = false; |
3268 | 3287 | ||
@@ -3283,7 +3302,7 @@ int r600_irq_process(struct radeon_device *rdev) | |||
3283 | 3302 | ||
3284 | restart_ih: | 3303 | restart_ih: |
3285 | /* display interrupts */ | 3304 | /* display interrupts */ |
3286 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | 3305 | r600_irq_ack(rdev); |
3287 | 3306 | ||
3288 | rdev->ih.wptr = wptr; | 3307 | rdev->ih.wptr = wptr; |
3289 | while (rptr != wptr) { | 3308 | while (rptr != wptr) { |
@@ -3296,17 +3315,21 @@ restart_ih: | |||
3296 | case 1: /* D1 vblank/vline */ | 3315 | case 1: /* D1 vblank/vline */ |
3297 | switch (src_data) { | 3316 | switch (src_data) { |
3298 | case 0: /* D1 vblank */ | 3317 | case 0: /* D1 vblank */ |
3299 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | 3318 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { |
3300 | drm_handle_vblank(rdev->ddev, 0); | 3319 | if (rdev->irq.crtc_vblank_int[0]) { |
3301 | rdev->pm.vblank_sync = true; | 3320 | drm_handle_vblank(rdev->ddev, 0); |
3302 | wake_up(&rdev->irq.vblank_queue); | 3321 | rdev->pm.vblank_sync = true; |
3303 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | 3322 | wake_up(&rdev->irq.vblank_queue); |
3323 | } | ||
3324 | if (rdev->irq.pflip[0]) | ||
3325 | radeon_crtc_handle_flip(rdev, 0); | ||
3326 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
3304 | DRM_DEBUG("IH: D1 vblank\n"); | 3327 | DRM_DEBUG("IH: D1 vblank\n"); |
3305 | } | 3328 | } |
3306 | break; | 3329 | break; |
3307 | case 1: /* D1 vline */ | 3330 | case 1: /* D1 vline */ |
3308 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | 3331 | if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { |
3309 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | 3332 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; |
3310 | DRM_DEBUG("IH: D1 vline\n"); | 3333 | DRM_DEBUG("IH: D1 vline\n"); |
3311 | } | 3334 | } |
3312 | break; | 3335 | break; |
@@ -3318,17 +3341,21 @@ restart_ih: | |||
3318 | case 5: /* D2 vblank/vline */ | 3341 | case 5: /* D2 vblank/vline */ |
3319 | switch (src_data) { | 3342 | switch (src_data) { |
3320 | case 0: /* D2 vblank */ | 3343 | case 0: /* D2 vblank */ |
3321 | if (disp_int & LB_D2_VBLANK_INTERRUPT) { | 3344 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { |
3322 | drm_handle_vblank(rdev->ddev, 1); | 3345 | if (rdev->irq.crtc_vblank_int[1]) { |
3323 | rdev->pm.vblank_sync = true; | 3346 | drm_handle_vblank(rdev->ddev, 1); |
3324 | wake_up(&rdev->irq.vblank_queue); | 3347 | rdev->pm.vblank_sync = true; |
3325 | disp_int &= ~LB_D2_VBLANK_INTERRUPT; | 3348 | wake_up(&rdev->irq.vblank_queue); |
3349 | } | ||
3350 | if (rdev->irq.pflip[1]) | ||
3351 | radeon_crtc_handle_flip(rdev, 1); | ||
3352 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; | ||
3326 | DRM_DEBUG("IH: D2 vblank\n"); | 3353 | DRM_DEBUG("IH: D2 vblank\n"); |
3327 | } | 3354 | } |
3328 | break; | 3355 | break; |
3329 | case 1: /* D1 vline */ | 3356 | case 1: /* D1 vline */ |
3330 | if (disp_int & LB_D2_VLINE_INTERRUPT) { | 3357 | if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { |
3331 | disp_int &= ~LB_D2_VLINE_INTERRUPT; | 3358 | rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; |
3332 | DRM_DEBUG("IH: D2 vline\n"); | 3359 | DRM_DEBUG("IH: D2 vline\n"); |
3333 | } | 3360 | } |
3334 | break; | 3361 | break; |
@@ -3340,43 +3367,43 @@ restart_ih: | |||
3340 | case 19: /* HPD/DAC hotplug */ | 3367 | case 19: /* HPD/DAC hotplug */ |
3341 | switch (src_data) { | 3368 | switch (src_data) { |
3342 | case 0: | 3369 | case 0: |
3343 | if (disp_int & DC_HPD1_INTERRUPT) { | 3370 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { |
3344 | disp_int &= ~DC_HPD1_INTERRUPT; | 3371 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; |
3345 | queue_hotplug = true; | 3372 | queue_hotplug = true; |
3346 | DRM_DEBUG("IH: HPD1\n"); | 3373 | DRM_DEBUG("IH: HPD1\n"); |
3347 | } | 3374 | } |
3348 | break; | 3375 | break; |
3349 | case 1: | 3376 | case 1: |
3350 | if (disp_int & DC_HPD2_INTERRUPT) { | 3377 | if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { |
3351 | disp_int &= ~DC_HPD2_INTERRUPT; | 3378 | rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; |
3352 | queue_hotplug = true; | 3379 | queue_hotplug = true; |
3353 | DRM_DEBUG("IH: HPD2\n"); | 3380 | DRM_DEBUG("IH: HPD2\n"); |
3354 | } | 3381 | } |
3355 | break; | 3382 | break; |
3356 | case 4: | 3383 | case 4: |
3357 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | 3384 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { |
3358 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | 3385 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; |
3359 | queue_hotplug = true; | 3386 | queue_hotplug = true; |
3360 | DRM_DEBUG("IH: HPD3\n"); | 3387 | DRM_DEBUG("IH: HPD3\n"); |
3361 | } | 3388 | } |
3362 | break; | 3389 | break; |
3363 | case 5: | 3390 | case 5: |
3364 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | 3391 | if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { |
3365 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | 3392 | rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; |
3366 | queue_hotplug = true; | 3393 | queue_hotplug = true; |
3367 | DRM_DEBUG("IH: HPD4\n"); | 3394 | DRM_DEBUG("IH: HPD4\n"); |
3368 | } | 3395 | } |
3369 | break; | 3396 | break; |
3370 | case 10: | 3397 | case 10: |
3371 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | 3398 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { |
3372 | disp_int_cont2 &= ~DC_HPD5_INTERRUPT; | 3399 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; |
3373 | queue_hotplug = true; | 3400 | queue_hotplug = true; |
3374 | DRM_DEBUG("IH: HPD5\n"); | 3401 | DRM_DEBUG("IH: HPD5\n"); |
3375 | } | 3402 | } |
3376 | break; | 3403 | break; |
3377 | case 12: | 3404 | case 12: |
3378 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | 3405 | if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { |
3379 | disp_int_cont2 &= ~DC_HPD6_INTERRUPT; | 3406 | rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; |
3380 | queue_hotplug = true; | 3407 | queue_hotplug = true; |
3381 | DRM_DEBUG("IH: HPD6\n"); | 3408 | DRM_DEBUG("IH: HPD6\n"); |
3382 | } | 3409 | } |
@@ -3419,7 +3446,7 @@ restart_ih: | |||
3419 | if (wptr != rdev->ih.wptr) | 3446 | if (wptr != rdev->ih.wptr) |
3420 | goto restart_ih; | 3447 | goto restart_ih; |
3421 | if (queue_hotplug) | 3448 | if (queue_hotplug) |
3422 | queue_work(rdev->wq, &rdev->hotplug_work); | 3449 | schedule_work(&rdev->hotplug_work); |
3423 | rdev->ih.rptr = rptr; | 3450 | rdev->ih.rptr = rptr; |
3424 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | 3451 | WREG32(IH_RB_RPTR, rdev->ih.rptr); |
3425 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | 3452 | spin_unlock_irqrestore(&rdev->ih.lock, flags); |
@@ -3508,3 +3535,219 @@ void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | |||
3508 | } else | 3535 | } else |
3509 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | 3536 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); |
3510 | } | 3537 | } |
3538 | |||
3539 | void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes) | ||
3540 | { | ||
3541 | u32 link_width_cntl, mask, target_reg; | ||
3542 | |||
3543 | if (rdev->flags & RADEON_IS_IGP) | ||
3544 | return; | ||
3545 | |||
3546 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3547 | return; | ||
3548 | |||
3549 | /* x2 cards have a special sequence */ | ||
3550 | if (ASIC_IS_X2(rdev)) | ||
3551 | return; | ||
3552 | |||
3553 | /* FIXME wait for idle */ | ||
3554 | |||
3555 | switch (lanes) { | ||
3556 | case 0: | ||
3557 | mask = RADEON_PCIE_LC_LINK_WIDTH_X0; | ||
3558 | break; | ||
3559 | case 1: | ||
3560 | mask = RADEON_PCIE_LC_LINK_WIDTH_X1; | ||
3561 | break; | ||
3562 | case 2: | ||
3563 | mask = RADEON_PCIE_LC_LINK_WIDTH_X2; | ||
3564 | break; | ||
3565 | case 4: | ||
3566 | mask = RADEON_PCIE_LC_LINK_WIDTH_X4; | ||
3567 | break; | ||
3568 | case 8: | ||
3569 | mask = RADEON_PCIE_LC_LINK_WIDTH_X8; | ||
3570 | break; | ||
3571 | case 12: | ||
3572 | mask = RADEON_PCIE_LC_LINK_WIDTH_X12; | ||
3573 | break; | ||
3574 | case 16: | ||
3575 | default: | ||
3576 | mask = RADEON_PCIE_LC_LINK_WIDTH_X16; | ||
3577 | break; | ||
3578 | } | ||
3579 | |||
3580 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3581 | |||
3582 | if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == | ||
3583 | (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) | ||
3584 | return; | ||
3585 | |||
3586 | if (link_width_cntl & R600_PCIE_LC_UPCONFIGURE_DIS) | ||
3587 | return; | ||
3588 | |||
3589 | link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | | ||
3590 | RADEON_PCIE_LC_RECONFIG_NOW | | ||
3591 | R600_PCIE_LC_RENEGOTIATE_EN | | ||
3592 | R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3593 | link_width_cntl |= mask; | ||
3594 | |||
3595 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3596 | |||
3597 | /* some northbridges can renegotiate the link rather than requiring | ||
3598 | * a complete re-config. | ||
3599 | * e.g., AMD 780/790 northbridges (pci ids: 0x5956, 0x5957, 0x5958, etc.) | ||
3600 | */ | ||
3601 | if (link_width_cntl & R600_PCIE_LC_RENEGOTIATION_SUPPORT) | ||
3602 | link_width_cntl |= R600_PCIE_LC_RENEGOTIATE_EN | R600_PCIE_LC_UPCONFIGURE_SUPPORT; | ||
3603 | else | ||
3604 | link_width_cntl |= R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE; | ||
3605 | |||
3606 | WREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL, (link_width_cntl | | ||
3607 | RADEON_PCIE_LC_RECONFIG_NOW)); | ||
3608 | |||
3609 | if (rdev->family >= CHIP_RV770) | ||
3610 | target_reg = R700_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3611 | else | ||
3612 | target_reg = R600_TARGET_AND_CURRENT_PROFILE_INDEX; | ||
3613 | |||
3614 | /* wait for lane set to complete */ | ||
3615 | link_width_cntl = RREG32(target_reg); | ||
3616 | while (link_width_cntl == 0xffffffff) | ||
3617 | link_width_cntl = RREG32(target_reg); | ||
3618 | |||
3619 | } | ||
3620 | |||
3621 | int r600_get_pcie_lanes(struct radeon_device *rdev) | ||
3622 | { | ||
3623 | u32 link_width_cntl; | ||
3624 | |||
3625 | if (rdev->flags & RADEON_IS_IGP) | ||
3626 | return 0; | ||
3627 | |||
3628 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3629 | return 0; | ||
3630 | |||
3631 | /* x2 cards have a special sequence */ | ||
3632 | if (ASIC_IS_X2(rdev)) | ||
3633 | return 0; | ||
3634 | |||
3635 | /* FIXME wait for idle */ | ||
3636 | |||
3637 | link_width_cntl = RREG32_PCIE_P(RADEON_PCIE_LC_LINK_WIDTH_CNTL); | ||
3638 | |||
3639 | switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) { | ||
3640 | case RADEON_PCIE_LC_LINK_WIDTH_X0: | ||
3641 | return 0; | ||
3642 | case RADEON_PCIE_LC_LINK_WIDTH_X1: | ||
3643 | return 1; | ||
3644 | case RADEON_PCIE_LC_LINK_WIDTH_X2: | ||
3645 | return 2; | ||
3646 | case RADEON_PCIE_LC_LINK_WIDTH_X4: | ||
3647 | return 4; | ||
3648 | case RADEON_PCIE_LC_LINK_WIDTH_X8: | ||
3649 | return 8; | ||
3650 | case RADEON_PCIE_LC_LINK_WIDTH_X16: | ||
3651 | default: | ||
3652 | return 16; | ||
3653 | } | ||
3654 | } | ||
3655 | |||
3656 | static void r600_pcie_gen2_enable(struct radeon_device *rdev) | ||
3657 | { | ||
3658 | u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp; | ||
3659 | u16 link_cntl2; | ||
3660 | |||
3661 | if (rdev->flags & RADEON_IS_IGP) | ||
3662 | return; | ||
3663 | |||
3664 | if (!(rdev->flags & RADEON_IS_PCIE)) | ||
3665 | return; | ||
3666 | |||
3667 | /* x2 cards have a special sequence */ | ||
3668 | if (ASIC_IS_X2(rdev)) | ||
3669 | return; | ||
3670 | |||
3671 | /* only RV6xx+ chips are supported */ | ||
3672 | if (rdev->family <= CHIP_R600) | ||
3673 | return; | ||
3674 | |||
3675 | /* 55 nm r6xx asics */ | ||
3676 | if ((rdev->family == CHIP_RV670) || | ||
3677 | (rdev->family == CHIP_RV620) || | ||
3678 | (rdev->family == CHIP_RV635)) { | ||
3679 | /* advertise upconfig capability */ | ||
3680 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3681 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3682 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3683 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3684 | if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) { | ||
3685 | lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT; | ||
3686 | link_width_cntl &= ~(LC_LINK_WIDTH_MASK | | ||
3687 | LC_RECONFIG_ARC_MISSING_ESCAPE); | ||
3688 | link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN; | ||
3689 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3690 | } else { | ||
3691 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3692 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3693 | } | ||
3694 | } | ||
3695 | |||
3696 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3697 | if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) && | ||
3698 | (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { | ||
3699 | |||
3700 | /* 55 nm r6xx asics */ | ||
3701 | if ((rdev->family == CHIP_RV670) || | ||
3702 | (rdev->family == CHIP_RV620) || | ||
3703 | (rdev->family == CHIP_RV635)) { | ||
3704 | WREG32(MM_CFGREGS_CNTL, 0x8); | ||
3705 | link_cntl2 = RREG32(0x4088); | ||
3706 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3707 | /* not supported yet */ | ||
3708 | if (link_cntl2 & SELECTABLE_DEEMPHASIS) | ||
3709 | return; | ||
3710 | } | ||
3711 | |||
3712 | speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK; | ||
3713 | speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT); | ||
3714 | speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK; | ||
3715 | speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE; | ||
3716 | speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE; | ||
3717 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3718 | |||
3719 | tmp = RREG32(0x541c); | ||
3720 | WREG32(0x541c, tmp | 0x8); | ||
3721 | WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN); | ||
3722 | link_cntl2 = RREG16(0x4088); | ||
3723 | link_cntl2 &= ~TARGET_LINK_SPEED_MASK; | ||
3724 | link_cntl2 |= 0x2; | ||
3725 | WREG16(0x4088, link_cntl2); | ||
3726 | WREG32(MM_CFGREGS_CNTL, 0); | ||
3727 | |||
3728 | if ((rdev->family == CHIP_RV670) || | ||
3729 | (rdev->family == CHIP_RV620) || | ||
3730 | (rdev->family == CHIP_RV635)) { | ||
3731 | training_cntl = RREG32_PCIE_P(PCIE_LC_TRAINING_CNTL); | ||
3732 | training_cntl &= ~LC_POINT_7_PLUS_EN; | ||
3733 | WREG32_PCIE_P(PCIE_LC_TRAINING_CNTL, training_cntl); | ||
3734 | } else { | ||
3735 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3736 | speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; | ||
3737 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3738 | } | ||
3739 | |||
3740 | speed_cntl = RREG32_PCIE_P(PCIE_LC_SPEED_CNTL); | ||
3741 | speed_cntl |= LC_GEN2_EN_STRAP; | ||
3742 | WREG32_PCIE_P(PCIE_LC_SPEED_CNTL, speed_cntl); | ||
3743 | |||
3744 | } else { | ||
3745 | link_width_cntl = RREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL); | ||
3746 | /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ | ||
3747 | if (1) | ||
3748 | link_width_cntl |= LC_UPCONFIGURE_DIS; | ||
3749 | else | ||
3750 | link_width_cntl &= ~LC_UPCONFIGURE_DIS; | ||
3751 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | ||
3752 | } | ||
3753 | } | ||