Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/radeon: add support for interrupts on CIK (v5)

Todo:
- handle interrupts for compute queues

v2: add documentation
v3: update to latest reset code
v4: update to latest illegal CP handling
v5: fix missing break in interrupt handler switch statement

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+1021
+840
drivers/gpu/drm/radeon/cik.c
··· 62 62 MODULE_FIRMWARE("radeon/KABINI_mec.bin"); 63 63 MODULE_FIRMWARE("radeon/KABINI_rlc.bin"); 64 64 65 + extern int r600_ih_ring_alloc(struct radeon_device *rdev); 66 + extern void r600_ih_ring_fini(struct radeon_device *rdev); 65 67 extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); 66 68 extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); 67 69 extern void si_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); ··· 2920 2918 cik_rlc_start(rdev); 2921 2919 2922 2920 return 0; 2921 + } 2922 + 2923 + /* 2924 + * Interrupts 2925 + * Starting with r6xx, interrupts are handled via a ring buffer. 2926 + * Ring buffers are areas of GPU accessible memory that the GPU 2927 + * writes interrupt vectors into and the host reads vectors out of. 2928 + * There is a rptr (read pointer) that determines where the 2929 + * host is currently reading, and a wptr (write pointer) 2930 + * which determines where the GPU has written. When the 2931 + * pointers are equal, the ring is idle. When the GPU 2932 + * writes vectors to the ring buffer, it increments the 2933 + * wptr. When there is an interrupt, the host then starts 2934 + * fetching commands and processing them until the pointers are 2935 + * equal again at which point it updates the rptr. 2936 + */ 2937 + 2938 + /** 2939 + * cik_enable_interrupts - Enable the interrupt ring buffer 2940 + * 2941 + * @rdev: radeon_device pointer 2942 + * 2943 + * Enable the interrupt ring buffer (CIK). 2944 + */ 2945 + static void cik_enable_interrupts(struct radeon_device *rdev) 2946 + { 2947 + u32 ih_cntl = RREG32(IH_CNTL); 2948 + u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 2949 + 2950 + ih_cntl |= ENABLE_INTR; 2951 + ih_rb_cntl |= IH_RB_ENABLE; 2952 + WREG32(IH_CNTL, ih_cntl); 2953 + WREG32(IH_RB_CNTL, ih_rb_cntl); 2954 + rdev->ih.enabled = true; 2955 + } 2956 + 2957 + /** 2958 + * cik_disable_interrupts - Disable the interrupt ring buffer 2959 + * 2960 + * @rdev: radeon_device pointer 2961 + * 2962 + * Disable the interrupt ring buffer (CIK). 2963 + */ 2964 + static void cik_disable_interrupts(struct radeon_device *rdev) 2965 + { 2966 + u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 2967 + u32 ih_cntl = RREG32(IH_CNTL); 2968 + 2969 + ih_rb_cntl &= ~IH_RB_ENABLE; 2970 + ih_cntl &= ~ENABLE_INTR; 2971 + WREG32(IH_RB_CNTL, ih_rb_cntl); 2972 + WREG32(IH_CNTL, ih_cntl); 2973 + /* set rptr, wptr to 0 */ 2974 + WREG32(IH_RB_RPTR, 0); 2975 + WREG32(IH_RB_WPTR, 0); 2976 + rdev->ih.enabled = false; 2977 + rdev->ih.rptr = 0; 2978 + } 2979 + 2980 + /** 2981 + * cik_disable_interrupt_state - Disable all interrupt sources 2982 + * 2983 + * @rdev: radeon_device pointer 2984 + * 2985 + * Clear all interrupt enable bits used by the driver (CIK). 2986 + */ 2987 + static void cik_disable_interrupt_state(struct radeon_device *rdev) 2988 + { 2989 + u32 tmp; 2990 + 2991 + /* gfx ring */ 2992 + WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 2993 + /* compute queues */ 2994 + WREG32(CP_ME1_PIPE0_INT_CNTL, 0); 2995 + WREG32(CP_ME1_PIPE1_INT_CNTL, 0); 2996 + WREG32(CP_ME1_PIPE2_INT_CNTL, 0); 2997 + WREG32(CP_ME1_PIPE3_INT_CNTL, 0); 2998 + WREG32(CP_ME2_PIPE0_INT_CNTL, 0); 2999 + WREG32(CP_ME2_PIPE1_INT_CNTL, 0); 3000 + WREG32(CP_ME2_PIPE2_INT_CNTL, 0); 3001 + WREG32(CP_ME2_PIPE3_INT_CNTL, 0); 3002 + /* grbm */ 3003 + WREG32(GRBM_INT_CNTL, 0); 3004 + /* vline/vblank, etc. */ 3005 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); 3006 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); 3007 + if (rdev->num_crtc >= 4) { 3008 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); 3009 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); 3010 + } 3011 + if (rdev->num_crtc >= 6) { 3012 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); 3013 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); 3014 + } 3015 + 3016 + /* dac hotplug */ 3017 + WREG32(DAC_AUTODETECT_INT_CONTROL, 0); 3018 + 3019 + /* digital hotplug */ 3020 + tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3021 + WREG32(DC_HPD1_INT_CONTROL, tmp); 3022 + tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3023 + WREG32(DC_HPD2_INT_CONTROL, tmp); 3024 + tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3025 + WREG32(DC_HPD3_INT_CONTROL, tmp); 3026 + tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3027 + WREG32(DC_HPD4_INT_CONTROL, tmp); 3028 + tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3029 + WREG32(DC_HPD5_INT_CONTROL, tmp); 3030 + tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; 3031 + WREG32(DC_HPD6_INT_CONTROL, tmp); 3032 + 3033 + } 3034 + 3035 + /** 3036 + * cik_irq_init - init and enable the interrupt ring 3037 + * 3038 + * @rdev: radeon_device pointer 3039 + * 3040 + * Allocate a ring buffer for the interrupt controller, 3041 + * enable the RLC, disable interrupts, enable the IH 3042 + * ring buffer and enable it (CIK). 3043 + * Called at device load and reume. 3044 + * Returns 0 for success, errors for failure. 3045 + */ 3046 + static int cik_irq_init(struct radeon_device *rdev) 3047 + { 3048 + int ret = 0; 3049 + int rb_bufsz; 3050 + u32 interrupt_cntl, ih_cntl, ih_rb_cntl; 3051 + 3052 + /* allocate ring */ 3053 + ret = r600_ih_ring_alloc(rdev); 3054 + if (ret) 3055 + return ret; 3056 + 3057 + /* disable irqs */ 3058 + cik_disable_interrupts(rdev); 3059 + 3060 + /* init rlc */ 3061 + ret = cik_rlc_resume(rdev); 3062 + if (ret) { 3063 + r600_ih_ring_fini(rdev); 3064 + return ret; 3065 + } 3066 + 3067 + /* setup interrupt control */ 3068 + /* XXX this should actually be a bus address, not an MC address. same on older asics */ 3069 + WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); 3070 + interrupt_cntl = RREG32(INTERRUPT_CNTL); 3071 + /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi 3072 + * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN 3073 + */ 3074 + interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; 3075 + /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ 3076 + interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; 3077 + WREG32(INTERRUPT_CNTL, interrupt_cntl); 3078 + 3079 + WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); 3080 + rb_bufsz = drm_order(rdev->ih.ring_size / 4); 3081 + 3082 + ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | 3083 + IH_WPTR_OVERFLOW_CLEAR | 3084 + (rb_bufsz << 1)); 3085 + 3086 + if (rdev->wb.enabled) 3087 + ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; 3088 + 3089 + /* set the writeback address whether it's enabled or not */ 3090 + WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); 3091 + WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); 3092 + 3093 + WREG32(IH_RB_CNTL, ih_rb_cntl); 3094 + 3095 + /* set rptr, wptr to 0 */ 3096 + WREG32(IH_RB_RPTR, 0); 3097 + WREG32(IH_RB_WPTR, 0); 3098 + 3099 + /* Default settings for IH_CNTL (disabled at first) */ 3100 + ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0); 3101 + /* RPTR_REARM only works if msi's are enabled */ 3102 + if (rdev->msi_enabled) 3103 + ih_cntl |= RPTR_REARM; 3104 + WREG32(IH_CNTL, ih_cntl); 3105 + 3106 + /* force the active interrupt state to all disabled */ 3107 + cik_disable_interrupt_state(rdev); 3108 + 3109 + pci_set_master(rdev->pdev); 3110 + 3111 + /* enable irqs */ 3112 + cik_enable_interrupts(rdev); 3113 + 3114 + return ret; 3115 + } 3116 + 3117 + /** 3118 + * cik_irq_set - enable/disable interrupt sources 3119 + * 3120 + * @rdev: radeon_device pointer 3121 + * 3122 + * Enable interrupt sources on the GPU (vblanks, hpd, 3123 + * etc.) (CIK). 3124 + * Returns 0 for success, errors for failure. 3125 + */ 3126 + int cik_irq_set(struct radeon_device *rdev) 3127 + { 3128 + u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE | 3129 + PRIV_INSTR_INT_ENABLE | PRIV_REG_INT_ENABLE; 3130 + u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; 3131 + u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; 3132 + u32 grbm_int_cntl = 0; 3133 + 3134 + if (!rdev->irq.installed) { 3135 + WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 3136 + return -EINVAL; 3137 + } 3138 + /* don't enable anything if the ih is disabled */ 3139 + if (!rdev->ih.enabled) { 3140 + cik_disable_interrupts(rdev); 3141 + /* force the active interrupt state to all disabled */ 3142 + cik_disable_interrupt_state(rdev); 3143 + return 0; 3144 + } 3145 + 3146 + hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; 3147 + hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; 3148 + hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; 3149 + hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; 3150 + hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; 3151 + hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; 3152 + 3153 + /* enable CP interrupts on all rings */ 3154 + if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { 3155 + DRM_DEBUG("cik_irq_set: sw int gfx\n"); 3156 + cp_int_cntl |= TIME_STAMP_INT_ENABLE; 3157 + } 3158 + /* TODO: compute queues! */ 3159 + /* CP_ME[1-2]_PIPE[0-3]_INT_CNTL */ 3160 + 3161 + if (rdev->irq.crtc_vblank_int[0] || 3162 + atomic_read(&rdev->irq.pflip[0])) { 3163 + DRM_DEBUG("cik_irq_set: vblank 0\n"); 3164 + crtc1 |= VBLANK_INTERRUPT_MASK; 3165 + } 3166 + if (rdev->irq.crtc_vblank_int[1] || 3167 + atomic_read(&rdev->irq.pflip[1])) { 3168 + DRM_DEBUG("cik_irq_set: vblank 1\n"); 3169 + crtc2 |= VBLANK_INTERRUPT_MASK; 3170 + } 3171 + if (rdev->irq.crtc_vblank_int[2] || 3172 + atomic_read(&rdev->irq.pflip[2])) { 3173 + DRM_DEBUG("cik_irq_set: vblank 2\n"); 3174 + crtc3 |= VBLANK_INTERRUPT_MASK; 3175 + } 3176 + if (rdev->irq.crtc_vblank_int[3] || 3177 + atomic_read(&rdev->irq.pflip[3])) { 3178 + DRM_DEBUG("cik_irq_set: vblank 3\n"); 3179 + crtc4 |= VBLANK_INTERRUPT_MASK; 3180 + } 3181 + if (rdev->irq.crtc_vblank_int[4] || 3182 + atomic_read(&rdev->irq.pflip[4])) { 3183 + DRM_DEBUG("cik_irq_set: vblank 4\n"); 3184 + crtc5 |= VBLANK_INTERRUPT_MASK; 3185 + } 3186 + if (rdev->irq.crtc_vblank_int[5] || 3187 + atomic_read(&rdev->irq.pflip[5])) { 3188 + DRM_DEBUG("cik_irq_set: vblank 5\n"); 3189 + crtc6 |= VBLANK_INTERRUPT_MASK; 3190 + } 3191 + if (rdev->irq.hpd[0]) { 3192 + DRM_DEBUG("cik_irq_set: hpd 1\n"); 3193 + hpd1 |= DC_HPDx_INT_EN; 3194 + } 3195 + if (rdev->irq.hpd[1]) { 3196 + DRM_DEBUG("cik_irq_set: hpd 2\n"); 3197 + hpd2 |= DC_HPDx_INT_EN; 3198 + } 3199 + if (rdev->irq.hpd[2]) { 3200 + DRM_DEBUG("cik_irq_set: hpd 3\n"); 3201 + hpd3 |= DC_HPDx_INT_EN; 3202 + } 3203 + if (rdev->irq.hpd[3]) { 3204 + DRM_DEBUG("cik_irq_set: hpd 4\n"); 3205 + hpd4 |= DC_HPDx_INT_EN; 3206 + } 3207 + if (rdev->irq.hpd[4]) { 3208 + DRM_DEBUG("cik_irq_set: hpd 5\n"); 3209 + hpd5 |= DC_HPDx_INT_EN; 3210 + } 3211 + if (rdev->irq.hpd[5]) { 3212 + DRM_DEBUG("cik_irq_set: hpd 6\n"); 3213 + hpd6 |= DC_HPDx_INT_EN; 3214 + } 3215 + 3216 + WREG32(CP_INT_CNTL_RING0, cp_int_cntl); 3217 + 3218 + WREG32(GRBM_INT_CNTL, grbm_int_cntl); 3219 + 3220 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); 3221 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); 3222 + if (rdev->num_crtc >= 4) { 3223 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); 3224 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); 3225 + } 3226 + if (rdev->num_crtc >= 6) { 3227 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); 3228 + WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); 3229 + } 3230 + 3231 + WREG32(DC_HPD1_INT_CONTROL, hpd1); 3232 + WREG32(DC_HPD2_INT_CONTROL, hpd2); 3233 + WREG32(DC_HPD3_INT_CONTROL, hpd3); 3234 + WREG32(DC_HPD4_INT_CONTROL, hpd4); 3235 + WREG32(DC_HPD5_INT_CONTROL, hpd5); 3236 + WREG32(DC_HPD6_INT_CONTROL, hpd6); 3237 + 3238 + return 0; 3239 + } 3240 + 3241 + /** 3242 + * cik_irq_ack - ack interrupt sources 3243 + * 3244 + * @rdev: radeon_device pointer 3245 + * 3246 + * Ack interrupt sources on the GPU (vblanks, hpd, 3247 + * etc.) (CIK). Certain interrupts sources are sw 3248 + * generated and do not require an explicit ack. 3249 + */ 3250 + static inline void cik_irq_ack(struct radeon_device *rdev) 3251 + { 3252 + u32 tmp; 3253 + 3254 + rdev->irq.stat_regs.cik.disp_int = RREG32(DISP_INTERRUPT_STATUS); 3255 + rdev->irq.stat_regs.cik.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); 3256 + rdev->irq.stat_regs.cik.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); 3257 + rdev->irq.stat_regs.cik.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); 3258 + rdev->irq.stat_regs.cik.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); 3259 + rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); 3260 + rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6); 3261 + 3262 + if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) 3263 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); 3264 + if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) 3265 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); 3266 + if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) 3267 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); 3268 + if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) 3269 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); 3270 + 3271 + if (rdev->num_crtc >= 4) { 3272 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) 3273 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); 3274 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) 3275 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); 3276 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) 3277 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); 3278 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) 3279 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); 3280 + } 3281 + 3282 + if (rdev->num_crtc >= 6) { 3283 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) 3284 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); 3285 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) 3286 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); 3287 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) 3288 + WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); 3289 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) 3290 + WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); 3291 + } 3292 + 3293 + if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) { 3294 + tmp = RREG32(DC_HPD1_INT_CONTROL); 3295 + tmp |= DC_HPDx_INT_ACK; 3296 + WREG32(DC_HPD1_INT_CONTROL, tmp); 3297 + } 3298 + if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) { 3299 + tmp = RREG32(DC_HPD2_INT_CONTROL); 3300 + tmp |= DC_HPDx_INT_ACK; 3301 + WREG32(DC_HPD2_INT_CONTROL, tmp); 3302 + } 3303 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) { 3304 + tmp = RREG32(DC_HPD3_INT_CONTROL); 3305 + tmp |= DC_HPDx_INT_ACK; 3306 + WREG32(DC_HPD3_INT_CONTROL, tmp); 3307 + } 3308 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) { 3309 + tmp = RREG32(DC_HPD4_INT_CONTROL); 3310 + tmp |= DC_HPDx_INT_ACK; 3311 + WREG32(DC_HPD4_INT_CONTROL, tmp); 3312 + } 3313 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) { 3314 + tmp = RREG32(DC_HPD5_INT_CONTROL); 3315 + tmp |= DC_HPDx_INT_ACK; 3316 + WREG32(DC_HPD5_INT_CONTROL, tmp); 3317 + } 3318 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { 3319 + tmp = RREG32(DC_HPD5_INT_CONTROL); 3320 + tmp |= DC_HPDx_INT_ACK; 3321 + WREG32(DC_HPD6_INT_CONTROL, tmp); 3322 + } 3323 + } 3324 + 3325 + /** 3326 + * cik_irq_disable - disable interrupts 3327 + * 3328 + * @rdev: radeon_device pointer 3329 + * 3330 + * Disable interrupts on the hw (CIK). 3331 + */ 3332 + static void cik_irq_disable(struct radeon_device *rdev) 3333 + { 3334 + cik_disable_interrupts(rdev); 3335 + /* Wait and acknowledge irq */ 3336 + mdelay(1); 3337 + cik_irq_ack(rdev); 3338 + cik_disable_interrupt_state(rdev); 3339 + } 3340 + 3341 + /** 3342 + * cik_irq_disable - disable interrupts for suspend 3343 + * 3344 + * @rdev: radeon_device pointer 3345 + * 3346 + * Disable interrupts and stop the RLC (CIK). 3347 + * Used for suspend. 3348 + */ 3349 + static void cik_irq_suspend(struct radeon_device *rdev) 3350 + { 3351 + cik_irq_disable(rdev); 3352 + cik_rlc_stop(rdev); 3353 + } 3354 + 3355 + /** 3356 + * cik_irq_fini - tear down interrupt support 3357 + * 3358 + * @rdev: radeon_device pointer 3359 + * 3360 + * Disable interrupts on the hw and free the IH ring 3361 + * buffer (CIK). 3362 + * Used for driver unload. 3363 + */ 3364 + static void cik_irq_fini(struct radeon_device *rdev) 3365 + { 3366 + cik_irq_suspend(rdev); 3367 + r600_ih_ring_fini(rdev); 3368 + } 3369 + 3370 + /** 3371 + * cik_get_ih_wptr - get the IH ring buffer wptr 3372 + * 3373 + * @rdev: radeon_device pointer 3374 + * 3375 + * Get the IH ring buffer wptr from either the register 3376 + * or the writeback memory buffer (CIK). Also check for 3377 + * ring buffer overflow and deal with it. 3378 + * Used by cik_irq_process(). 3379 + * Returns the value of the wptr. 3380 + */ 3381 + static inline u32 cik_get_ih_wptr(struct radeon_device *rdev) 3382 + { 3383 + u32 wptr, tmp; 3384 + 3385 + if (rdev->wb.enabled) 3386 + wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); 3387 + else 3388 + wptr = RREG32(IH_RB_WPTR); 3389 + 3390 + if (wptr & RB_OVERFLOW) { 3391 + /* When a ring buffer overflow happen start parsing interrupt 3392 + * from the last not overwritten vector (wptr + 16). Hopefully 3393 + * this should allow us to catchup. 3394 + */ 3395 + dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", 3396 + wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); 3397 + rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; 3398 + tmp = RREG32(IH_RB_CNTL); 3399 + tmp |= IH_WPTR_OVERFLOW_CLEAR; 3400 + WREG32(IH_RB_CNTL, tmp); 3401 + } 3402 + return (wptr & rdev->ih.ptr_mask); 3403 + } 3404 + 3405 + /* CIK IV Ring 3406 + * Each IV ring entry is 128 bits: 3407 + * [7:0] - interrupt source id 3408 + * [31:8] - reserved 3409 + * [59:32] - interrupt source data 3410 + * [63:60] - reserved 3411 + * [71:64] - RINGID: ME_ID [1:0], PIPE_ID[1:0], QUEUE_ID[2:0] 3412 + * QUEUE_ID - for compute, which of the 8 queues owned by the dispatcher 3413 + * - for gfx, hw shader state (0=PS...5=LS, 6=CS) 3414 + * ME_ID - 0 = gfx, 1 = first 4 CS pipes, 2 = second 4 CS pipes 3415 + * PIPE_ID - ME0 0=3D 3416 + * - ME1&2 compute dispatcher (4 pipes each) 3417 + * [79:72] - VMID 3418 + * [95:80] - PASID 3419 + * [127:96] - reserved 3420 + */ 3421 + /** 3422 + * cik_irq_process - interrupt handler 3423 + * 3424 + * @rdev: radeon_device pointer 3425 + * 3426 + * Interrupt hander (CIK). Walk the IH ring, 3427 + * ack interrupts and schedule work to handle 3428 + * interrupt events. 3429 + * Returns irq process return code. 3430 + */ 3431 + int cik_irq_process(struct radeon_device *rdev) 3432 + { 3433 + u32 wptr; 3434 + u32 rptr; 3435 + u32 src_id, src_data, ring_id; 3436 + u8 me_id, pipe_id, queue_id; 3437 + u32 ring_index; 3438 + bool queue_hotplug = false; 3439 + bool queue_reset = false; 3440 + 3441 + if (!rdev->ih.enabled || rdev->shutdown) 3442 + return IRQ_NONE; 3443 + 3444 + wptr = cik_get_ih_wptr(rdev); 3445 + 3446 + restart_ih: 3447 + /* is somebody else already processing irqs? */ 3448 + if (atomic_xchg(&rdev->ih.lock, 1)) 3449 + return IRQ_NONE; 3450 + 3451 + rptr = rdev->ih.rptr; 3452 + DRM_DEBUG("cik_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 3453 + 3454 + /* Order reading of wptr vs. reading of IH ring data */ 3455 + rmb(); 3456 + 3457 + /* display interrupts */ 3458 + cik_irq_ack(rdev); 3459 + 3460 + while (rptr != wptr) { 3461 + /* wptr/rptr are in bytes! */ 3462 + ring_index = rptr / 4; 3463 + src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; 3464 + src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; 3465 + ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; 3466 + /* XXX check the bitfield order! */ 3467 + me_id = (ring_id & 0x60) >> 5; 3468 + pipe_id = (ring_id & 0x18) >> 3; 3469 + queue_id = (ring_id & 0x7) >> 0; 3470 + 3471 + switch (src_id) { 3472 + case 1: /* D1 vblank/vline */ 3473 + switch (src_data) { 3474 + case 0: /* D1 vblank */ 3475 + if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) { 3476 + if (rdev->irq.crtc_vblank_int[0]) { 3477 + drm_handle_vblank(rdev->ddev, 0); 3478 + rdev->pm.vblank_sync = true; 3479 + wake_up(&rdev->irq.vblank_queue); 3480 + } 3481 + if (atomic_read(&rdev->irq.pflip[0])) 3482 + radeon_crtc_handle_flip(rdev, 0); 3483 + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; 3484 + DRM_DEBUG("IH: D1 vblank\n"); 3485 + } 3486 + break; 3487 + case 1: /* D1 vline */ 3488 + if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) { 3489 + rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; 3490 + DRM_DEBUG("IH: D1 vline\n"); 3491 + } 3492 + break; 3493 + default: 3494 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3495 + break; 3496 + } 3497 + break; 3498 + case 2: /* D2 vblank/vline */ 3499 + switch (src_data) { 3500 + case 0: /* D2 vblank */ 3501 + if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { 3502 + if (rdev->irq.crtc_vblank_int[1]) { 3503 + drm_handle_vblank(rdev->ddev, 1); 3504 + rdev->pm.vblank_sync = true; 3505 + wake_up(&rdev->irq.vblank_queue); 3506 + } 3507 + if (atomic_read(&rdev->irq.pflip[1])) 3508 + radeon_crtc_handle_flip(rdev, 1); 3509 + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; 3510 + DRM_DEBUG("IH: D2 vblank\n"); 3511 + } 3512 + break; 3513 + case 1: /* D2 vline */ 3514 + if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) { 3515 + rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; 3516 + DRM_DEBUG("IH: D2 vline\n"); 3517 + } 3518 + break; 3519 + default: 3520 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3521 + break; 3522 + } 3523 + break; 3524 + case 3: /* D3 vblank/vline */ 3525 + switch (src_data) { 3526 + case 0: /* D3 vblank */ 3527 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { 3528 + if (rdev->irq.crtc_vblank_int[2]) { 3529 + drm_handle_vblank(rdev->ddev, 2); 3530 + rdev->pm.vblank_sync = true; 3531 + wake_up(&rdev->irq.vblank_queue); 3532 + } 3533 + if (atomic_read(&rdev->irq.pflip[2])) 3534 + radeon_crtc_handle_flip(rdev, 2); 3535 + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; 3536 + DRM_DEBUG("IH: D3 vblank\n"); 3537 + } 3538 + break; 3539 + case 1: /* D3 vline */ 3540 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { 3541 + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; 3542 + DRM_DEBUG("IH: D3 vline\n"); 3543 + } 3544 + break; 3545 + default: 3546 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3547 + break; 3548 + } 3549 + break; 3550 + case 4: /* D4 vblank/vline */ 3551 + switch (src_data) { 3552 + case 0: /* D4 vblank */ 3553 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { 3554 + if (rdev->irq.crtc_vblank_int[3]) { 3555 + drm_handle_vblank(rdev->ddev, 3); 3556 + rdev->pm.vblank_sync = true; 3557 + wake_up(&rdev->irq.vblank_queue); 3558 + } 3559 + if (atomic_read(&rdev->irq.pflip[3])) 3560 + radeon_crtc_handle_flip(rdev, 3); 3561 + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; 3562 + DRM_DEBUG("IH: D4 vblank\n"); 3563 + } 3564 + break; 3565 + case 1: /* D4 vline */ 3566 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { 3567 + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; 3568 + DRM_DEBUG("IH: D4 vline\n"); 3569 + } 3570 + break; 3571 + default: 3572 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3573 + break; 3574 + } 3575 + break; 3576 + case 5: /* D5 vblank/vline */ 3577 + switch (src_data) { 3578 + case 0: /* D5 vblank */ 3579 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { 3580 + if (rdev->irq.crtc_vblank_int[4]) { 3581 + drm_handle_vblank(rdev->ddev, 4); 3582 + rdev->pm.vblank_sync = true; 3583 + wake_up(&rdev->irq.vblank_queue); 3584 + } 3585 + if (atomic_read(&rdev->irq.pflip[4])) 3586 + radeon_crtc_handle_flip(rdev, 4); 3587 + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; 3588 + DRM_DEBUG("IH: D5 vblank\n"); 3589 + } 3590 + break; 3591 + case 1: /* D5 vline */ 3592 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { 3593 + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; 3594 + DRM_DEBUG("IH: D5 vline\n"); 3595 + } 3596 + break; 3597 + default: 3598 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3599 + break; 3600 + } 3601 + break; 3602 + case 6: /* D6 vblank/vline */ 3603 + switch (src_data) { 3604 + case 0: /* D6 vblank */ 3605 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { 3606 + if (rdev->irq.crtc_vblank_int[5]) { 3607 + drm_handle_vblank(rdev->ddev, 5); 3608 + rdev->pm.vblank_sync = true; 3609 + wake_up(&rdev->irq.vblank_queue); 3610 + } 3611 + if (atomic_read(&rdev->irq.pflip[5])) 3612 + radeon_crtc_handle_flip(rdev, 5); 3613 + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; 3614 + DRM_DEBUG("IH: D6 vblank\n"); 3615 + } 3616 + break; 3617 + case 1: /* D6 vline */ 3618 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { 3619 + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; 3620 + DRM_DEBUG("IH: D6 vline\n"); 3621 + } 3622 + break; 3623 + default: 3624 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3625 + break; 3626 + } 3627 + break; 3628 + case 42: /* HPD hotplug */ 3629 + switch (src_data) { 3630 + case 0: 3631 + if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) { 3632 + rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; 3633 + queue_hotplug = true; 3634 + DRM_DEBUG("IH: HPD1\n"); 3635 + } 3636 + break; 3637 + case 1: 3638 + if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) { 3639 + rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; 3640 + queue_hotplug = true; 3641 + DRM_DEBUG("IH: HPD2\n"); 3642 + } 3643 + break; 3644 + case 2: 3645 + if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) { 3646 + rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; 3647 + queue_hotplug = true; 3648 + DRM_DEBUG("IH: HPD3\n"); 3649 + } 3650 + break; 3651 + case 3: 3652 + if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) { 3653 + rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; 3654 + queue_hotplug = true; 3655 + DRM_DEBUG("IH: HPD4\n"); 3656 + } 3657 + break; 3658 + case 4: 3659 + if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) { 3660 + rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; 3661 + queue_hotplug = true; 3662 + DRM_DEBUG("IH: HPD5\n"); 3663 + } 3664 + break; 3665 + case 5: 3666 + if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { 3667 + rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; 3668 + queue_hotplug = true; 3669 + DRM_DEBUG("IH: HPD6\n"); 3670 + } 3671 + break; 3672 + default: 3673 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3674 + break; 3675 + } 3676 + break; 3677 + case 176: /* GFX RB CP_INT */ 3678 + case 177: /* GFX IB CP_INT */ 3679 + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 3680 + break; 3681 + case 181: /* CP EOP event */ 3682 + DRM_DEBUG("IH: CP EOP\n"); 3683 + switch (me_id) { 3684 + case 0: 3685 + radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 3686 + break; 3687 + case 1: 3688 + /* XXX compute */ 3689 + break; 3690 + case 2: 3691 + /* XXX compute */ 3692 + break; 3693 + } 3694 + break; 3695 + case 184: /* CP Privileged reg access */ 3696 + DRM_ERROR("Illegal register access in command stream\n"); 3697 + /* XXX check the bitfield order! */ 3698 + me_id = (ring_id & 0x60) >> 5; 3699 + pipe_id = (ring_id & 0x18) >> 3; 3700 + queue_id = (ring_id & 0x7) >> 0; 3701 + switch (me_id) { 3702 + case 0: 3703 + /* This results in a full GPU reset, but all we need to do is soft 3704 + * reset the CP for gfx 3705 + */ 3706 + queue_reset = true; 3707 + break; 3708 + case 1: 3709 + /* XXX compute */ 3710 + break; 3711 + case 2: 3712 + /* XXX compute */ 3713 + break; 3714 + } 3715 + break; 3716 + case 185: /* CP Privileged inst */ 3717 + DRM_ERROR("Illegal instruction in command stream\n"); 3718 + switch (me_id) { 3719 + case 0: 3720 + /* This results in a full GPU reset, but all we need to do is soft 3721 + * reset the CP for gfx 3722 + */ 3723 + queue_reset = true; 3724 + break; 3725 + case 1: 3726 + /* XXX compute */ 3727 + break; 3728 + case 2: 3729 + /* XXX compute */ 3730 + break; 3731 + } 3732 + break; 3733 + case 233: /* GUI IDLE */ 3734 + DRM_DEBUG("IH: GUI idle\n"); 3735 + break; 3736 + default: 3737 + DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 3738 + break; 3739 + } 3740 + 3741 + /* wptr/rptr are in bytes! */ 3742 + rptr += 16; 3743 + rptr &= rdev->ih.ptr_mask; 3744 + } 3745 + if (queue_hotplug) 3746 + schedule_work(&rdev->hotplug_work); 3747 + if (queue_reset) 3748 + schedule_work(&rdev->reset_work); 3749 + rdev->ih.rptr = rptr; 3750 + WREG32(IH_RB_RPTR, rdev->ih.rptr); 3751 + atomic_set(&rdev->ih.lock, 0); 3752 + 3753 + /* make sure wptr hasn't changed while processing */ 3754 + wptr = cik_get_ih_wptr(rdev); 3755 + if (wptr != rptr) 3756 + goto restart_ih; 3757 + 3758 + return IRQ_HANDLED; 2923 3759 }
+170
drivers/gpu/drm/radeon/cikd.h
··· 178 178 #define HDP_MISC_CNTL 0x2F4C 179 179 #define HDP_FLUSH_INVALIDATE_CACHE (1 << 0) 180 180 181 + #define IH_RB_CNTL 0x3e00 182 + # define IH_RB_ENABLE (1 << 0) 183 + # define IH_RB_SIZE(x) ((x) << 1) /* log2 */ 184 + # define IH_RB_FULL_DRAIN_ENABLE (1 << 6) 185 + # define IH_WPTR_WRITEBACK_ENABLE (1 << 8) 186 + # define IH_WPTR_WRITEBACK_TIMER(x) ((x) << 9) /* log2 */ 187 + # define IH_WPTR_OVERFLOW_ENABLE (1 << 16) 188 + # define IH_WPTR_OVERFLOW_CLEAR (1 << 31) 189 + #define IH_RB_BASE 0x3e04 190 + #define IH_RB_RPTR 0x3e08 191 + #define IH_RB_WPTR 0x3e0c 192 + # define RB_OVERFLOW (1 << 0) 193 + # define WPTR_OFFSET_MASK 0x3fffc 194 + #define IH_RB_WPTR_ADDR_HI 0x3e10 195 + #define IH_RB_WPTR_ADDR_LO 0x3e14 196 + #define IH_CNTL 0x3e18 197 + # define ENABLE_INTR (1 << 0) 198 + # define IH_MC_SWAP(x) ((x) << 1) 199 + # define IH_MC_SWAP_NONE 0 200 + # define IH_MC_SWAP_16BIT 1 201 + # define IH_MC_SWAP_32BIT 2 202 + # define IH_MC_SWAP_64BIT 3 203 + # define RPTR_REARM (1 << 4) 204 + # define MC_WRREQ_CREDIT(x) ((x) << 15) 205 + # define MC_WR_CLEAN_CNT(x) ((x) << 20) 206 + # define MC_VMID(x) ((x) << 25) 207 + 181 208 #define CONFIG_MEMSIZE 0x5428 209 + 210 + #define INTERRUPT_CNTL 0x5468 211 + # define IH_DUMMY_RD_OVERRIDE (1 << 0) 212 + # define IH_DUMMY_RD_EN (1 << 1) 213 + # define IH_REQ_NONSNOOP_EN (1 << 3) 214 + # define GEN_IH_INT_EN (1 << 8) 215 + #define INTERRUPT_CNTL2 0x546c 182 216 183 217 #define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 184 218 ··· 236 202 #define CP9 (1 << 9) 237 203 #define SDMA0 (1 << 10) 238 204 #define SDMA1 (1 << 11) 205 + 206 + /* 0x6b24, 0x7724, 0x10324, 0x10f24, 0x11b24, 0x12724 */ 207 + #define LB_VLINE_STATUS 0x6b24 208 + # define VLINE_OCCURRED (1 << 0) 209 + # define VLINE_ACK (1 << 4) 210 + # define VLINE_STAT (1 << 12) 211 + # define VLINE_INTERRUPT (1 << 16) 212 + # define VLINE_INTERRUPT_TYPE (1 << 17) 213 + /* 0x6b2c, 0x772c, 0x1032c, 0x10f2c, 0x11b2c, 0x1272c */ 214 + #define LB_VBLANK_STATUS 0x6b2c 215 + # define VBLANK_OCCURRED (1 << 0) 216 + # define VBLANK_ACK (1 << 4) 217 + # define VBLANK_STAT (1 << 12) 218 + # define VBLANK_INTERRUPT (1 << 16) 219 + # define VBLANK_INTERRUPT_TYPE (1 << 17) 220 + 221 + /* 0x6b20, 0x7720, 0x10320, 0x10f20, 0x11b20, 0x12720 */ 222 + #define LB_INTERRUPT_MASK 0x6b20 223 + # define VBLANK_INTERRUPT_MASK (1 << 0) 224 + # define VLINE_INTERRUPT_MASK (1 << 4) 225 + # define VLINE2_INTERRUPT_MASK (1 << 8) 226 + 227 + #define DISP_INTERRUPT_STATUS 0x60f4 228 + # define LB_D1_VLINE_INTERRUPT (1 << 2) 229 + # define LB_D1_VBLANK_INTERRUPT (1 << 3) 230 + # define DC_HPD1_INTERRUPT (1 << 17) 231 + # define DC_HPD1_RX_INTERRUPT (1 << 18) 232 + # define DACA_AUTODETECT_INTERRUPT (1 << 22) 233 + # define DACB_AUTODETECT_INTERRUPT (1 << 23) 234 + # define DC_I2C_SW_DONE_INTERRUPT (1 << 24) 235 + # define DC_I2C_HW_DONE_INTERRUPT (1 << 25) 236 + #define DISP_INTERRUPT_STATUS_CONTINUE 0x60f8 237 + # define LB_D2_VLINE_INTERRUPT (1 << 2) 238 + # define LB_D2_VBLANK_INTERRUPT (1 << 3) 239 + # define DC_HPD2_INTERRUPT (1 << 17) 240 + # define DC_HPD2_RX_INTERRUPT (1 << 18) 241 + # define DISP_TIMER_INTERRUPT (1 << 24) 242 + #define DISP_INTERRUPT_STATUS_CONTINUE2 0x60fc 243 + # define LB_D3_VLINE_INTERRUPT (1 << 2) 244 + # define LB_D3_VBLANK_INTERRUPT (1 << 3) 245 + # define DC_HPD3_INTERRUPT (1 << 17) 246 + # define DC_HPD3_RX_INTERRUPT (1 << 18) 247 + #define DISP_INTERRUPT_STATUS_CONTINUE3 0x6100 248 + # define LB_D4_VLINE_INTERRUPT (1 << 2) 249 + # define LB_D4_VBLANK_INTERRUPT (1 << 3) 250 + # define DC_HPD4_INTERRUPT (1 << 17) 251 + # define DC_HPD4_RX_INTERRUPT (1 << 18) 252 + #define DISP_INTERRUPT_STATUS_CONTINUE4 0x614c 253 + # define LB_D5_VLINE_INTERRUPT (1 << 2) 254 + # define LB_D5_VBLANK_INTERRUPT (1 << 3) 255 + # define DC_HPD5_INTERRUPT (1 << 17) 256 + # define DC_HPD5_RX_INTERRUPT (1 << 18) 257 + #define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 258 + # define LB_D6_VLINE_INTERRUPT (1 << 2) 259 + # define LB_D6_VBLANK_INTERRUPT (1 << 3) 260 + # define DC_HPD6_INTERRUPT (1 << 17) 261 + # define DC_HPD6_RX_INTERRUPT (1 << 18) 262 + #define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780 263 + 264 + #define DAC_AUTODETECT_INT_CONTROL 0x67c8 265 + 266 + #define DC_HPD1_INT_STATUS 0x601c 267 + #define DC_HPD2_INT_STATUS 0x6028 268 + #define DC_HPD3_INT_STATUS 0x6034 269 + #define DC_HPD4_INT_STATUS 0x6040 270 + #define DC_HPD5_INT_STATUS 0x604c 271 + #define DC_HPD6_INT_STATUS 0x6058 272 + # define DC_HPDx_INT_STATUS (1 << 0) 273 + # define DC_HPDx_SENSE (1 << 1) 274 + # define DC_HPDx_SENSE_DELAYED (1 << 4) 275 + # define DC_HPDx_RX_INT_STATUS (1 << 8) 276 + 277 + #define DC_HPD1_INT_CONTROL 0x6020 278 + #define DC_HPD2_INT_CONTROL 0x602c 279 + #define DC_HPD3_INT_CONTROL 0x6038 280 + #define DC_HPD4_INT_CONTROL 0x6044 281 + #define DC_HPD5_INT_CONTROL 0x6050 282 + #define DC_HPD6_INT_CONTROL 0x605c 283 + # define DC_HPDx_INT_ACK (1 << 0) 284 + # define DC_HPDx_INT_POLARITY (1 << 8) 285 + # define DC_HPDx_INT_EN (1 << 16) 286 + # define DC_HPDx_RX_INT_ACK (1 << 20) 287 + # define DC_HPDx_RX_INT_EN (1 << 24) 288 + 289 + #define DC_HPD1_CONTROL 0x6024 290 + #define DC_HPD2_CONTROL 0x6030 291 + #define DC_HPD3_CONTROL 0x603c 292 + #define DC_HPD4_CONTROL 0x6048 293 + #define DC_HPD5_CONTROL 0x6054 294 + #define DC_HPD6_CONTROL 0x6060 295 + # define DC_HPDx_CONNECTION_TIMER(x) ((x) << 0) 296 + # define DC_HPDx_RX_INT_TIMER(x) ((x) << 16) 297 + # define DC_HPDx_EN (1 << 28) 239 298 240 299 #define GRBM_CNTL 0x8000 241 300 #define GRBM_READ_TIMEOUT(x) ((x) << 0) ··· 400 273 #define SOFT_RESET_CPF (1 << 17) /* CP fetcher shared by gfx and compute */ 401 274 #define SOFT_RESET_CPC (1 << 18) /* CP Compute (MEC1/2) */ 402 275 #define SOFT_RESET_CPG (1 << 19) /* CP GFX (PFP, ME, CE) */ 276 + 277 + #define GRBM_INT_CNTL 0x8060 278 + # define RDERR_INT_ENABLE (1 << 0) 279 + # define GUI_IDLE_INT_ENABLE (1 << 19) 403 280 404 281 #define CP_MEC_CNTL 0x8234 405 282 #define MEC_ME2_HALT (1 << 28) ··· 637 506 # define CP_RINGID2_INT_ENABLE (1 << 29) 638 507 # define CP_RINGID1_INT_ENABLE (1 << 30) 639 508 # define CP_RINGID0_INT_ENABLE (1 << 31) 509 + 510 + #define CP_INT_STATUS_RING0 0xC1B4 511 + # define PRIV_INSTR_INT_STAT (1 << 22) 512 + # define PRIV_REG_INT_STAT (1 << 23) 513 + # define TIME_STAMP_INT_STAT (1 << 26) 514 + # define CP_RINGID2_INT_STAT (1 << 29) 515 + # define CP_RINGID1_INT_STAT (1 << 30) 516 + # define CP_RINGID0_INT_STAT (1 << 31) 517 + 518 + #define CP_ME1_PIPE0_INT_CNTL 0xC214 519 + #define CP_ME1_PIPE1_INT_CNTL 0xC218 520 + #define CP_ME1_PIPE2_INT_CNTL 0xC21C 521 + #define CP_ME1_PIPE3_INT_CNTL 0xC220 522 + #define CP_ME2_PIPE0_INT_CNTL 0xC224 523 + #define CP_ME2_PIPE1_INT_CNTL 0xC228 524 + #define CP_ME2_PIPE2_INT_CNTL 0xC22C 525 + #define CP_ME2_PIPE3_INT_CNTL 0xC230 526 + # define DEQUEUE_REQUEST_INT_ENABLE (1 << 13) 527 + # define WRM_POLL_TIMEOUT_INT_ENABLE (1 << 17) 528 + # define PRIV_REG_INT_ENABLE (1 << 23) 529 + # define TIME_STAMP_INT_ENABLE (1 << 26) 530 + # define GENERIC2_INT_ENABLE (1 << 29) 531 + # define GENERIC1_INT_ENABLE (1 << 30) 532 + # define GENERIC0_INT_ENABLE (1 << 31) 533 + #define CP_ME1_PIPE0_INT_STATUS 0xC214 534 + #define CP_ME1_PIPE1_INT_STATUS 0xC218 535 + #define CP_ME1_PIPE2_INT_STATUS 0xC21C 536 + #define CP_ME1_PIPE3_INT_STATUS 0xC220 537 + #define CP_ME2_PIPE0_INT_STATUS 0xC224 538 + #define CP_ME2_PIPE1_INT_STATUS 0xC228 539 + #define CP_ME2_PIPE2_INT_STATUS 0xC22C 540 + #define CP_ME2_PIPE3_INT_STATUS 0xC230 541 + # define DEQUEUE_REQUEST_INT_STATUS (1 << 13) 542 + # define WRM_POLL_TIMEOUT_INT_STATUS (1 << 17) 543 + # define PRIV_REG_INT_STATUS (1 << 23) 544 + # define TIME_STAMP_INT_STATUS (1 << 26) 545 + # define GENERIC2_INT_STATUS (1 << 29) 546 + # define GENERIC1_INT_STATUS (1 << 30) 547 + # define GENERIC0_INT_STATUS (1 << 31) 640 548 641 549 #define CP_MAX_CONTEXT 0xC2B8 642 550
+11
drivers/gpu/drm/radeon/radeon.h
··· 600 600 u32 afmt_status6; 601 601 }; 602 602 603 + struct cik_irq_stat_regs { 604 + u32 disp_int; 605 + u32 disp_int_cont; 606 + u32 disp_int_cont2; 607 + u32 disp_int_cont3; 608 + u32 disp_int_cont4; 609 + u32 disp_int_cont5; 610 + u32 disp_int_cont6; 611 + }; 612 + 603 613 union radeon_irq_stat_regs { 604 614 struct r500_irq_stat_regs r500; 605 615 struct r600_irq_stat_regs r600; 606 616 struct evergreen_irq_stat_regs evergreen; 617 + struct cik_irq_stat_regs cik; 607 618 }; 608 619 609 620 #define RADEON_MAX_HPD_PINS 6