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/amdgpu: refactor MQD/HQD initialization v3

The MQD programming sequence currently exists in 3 different places.
Refactor it to absorb all the duplicates.

The success path remains mostly identical except for a slightly
different order in the non-kiq case. This shouldn't matter if the HQD
is disabled.

The error handling paths have been updated to deal with the new code
structure.

v2: the non-kiq path for gfxv8 was dropped in the rebase
v3: split MEC_HPD_SIZE rename, dropped doorbell changes

Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Andres Rodriguez and committed by
Alex Deucher
34130fb1 268cb4c7

+277 -252
+243 -208
drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
··· 2944 2944 u32 interrupt_queue[64]; 2945 2945 }; 2946 2946 2947 + static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev, int me, int pipe) 2948 + { 2949 + u64 eop_gpu_addr; 2950 + u32 tmp; 2951 + size_t eop_offset = me * pipe * GFX7_MEC_HPD_SIZE * 2; 2952 + 2953 + mutex_lock(&adev->srbm_mutex); 2954 + eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + eop_offset; 2955 + 2956 + cik_srbm_select(adev, me, pipe, 0, 0); 2957 + 2958 + /* write the EOP addr */ 2959 + WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); 2960 + WREG32(mmCP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8); 2961 + 2962 + /* set the VMID assigned */ 2963 + WREG32(mmCP_HPD_EOP_VMID, 0); 2964 + 2965 + /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ 2966 + tmp = RREG32(mmCP_HPD_EOP_CONTROL); 2967 + tmp &= ~CP_HPD_EOP_CONTROL__EOP_SIZE_MASK; 2968 + tmp |= order_base_2(GFX7_MEC_HPD_SIZE / 8); 2969 + WREG32(mmCP_HPD_EOP_CONTROL, tmp); 2970 + 2971 + cik_srbm_select(adev, 0, 0, 0, 0); 2972 + mutex_unlock(&adev->srbm_mutex); 2973 + } 2974 + 2975 + static int gfx_v7_0_mqd_deactivate(struct amdgpu_device *adev) 2976 + { 2977 + int i; 2978 + 2979 + /* disable the queue if it's active */ 2980 + if (RREG32(mmCP_HQD_ACTIVE) & 1) { 2981 + WREG32(mmCP_HQD_DEQUEUE_REQUEST, 1); 2982 + for (i = 0; i < adev->usec_timeout; i++) { 2983 + if (!(RREG32(mmCP_HQD_ACTIVE) & 1)) 2984 + break; 2985 + udelay(1); 2986 + } 2987 + 2988 + if (i == adev->usec_timeout) 2989 + return -ETIMEDOUT; 2990 + 2991 + WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0); 2992 + WREG32(mmCP_HQD_PQ_RPTR, 0); 2993 + WREG32(mmCP_HQD_PQ_WPTR, 0); 2994 + } 2995 + 2996 + return 0; 2997 + } 2998 + 2999 + static void gfx_v7_0_mqd_init(struct amdgpu_device *adev, 3000 + struct bonaire_mqd *mqd, 3001 + uint64_t mqd_gpu_addr, 3002 + struct amdgpu_ring *ring) 3003 + { 3004 + u64 hqd_gpu_addr; 3005 + u64 wb_gpu_addr; 3006 + 3007 + /* init the mqd struct */ 3008 + memset(mqd, 0, sizeof(struct bonaire_mqd)); 3009 + 3010 + mqd->header = 0xC0310800; 3011 + mqd->static_thread_mgmt01[0] = 0xffffffff; 3012 + mqd->static_thread_mgmt01[1] = 0xffffffff; 3013 + mqd->static_thread_mgmt23[0] = 0xffffffff; 3014 + mqd->static_thread_mgmt23[1] = 0xffffffff; 3015 + 3016 + /* enable doorbell? */ 3017 + mqd->queue_state.cp_hqd_pq_doorbell_control = 3018 + RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); 3019 + if (ring->use_doorbell) 3020 + mqd->queue_state.cp_hqd_pq_doorbell_control |= CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3021 + else 3022 + mqd->queue_state.cp_hqd_pq_doorbell_control &= ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3023 + 3024 + /* set the pointer to the MQD */ 3025 + mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc; 3026 + mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr); 3027 + 3028 + /* set MQD vmid to 0 */ 3029 + mqd->queue_state.cp_mqd_control = RREG32(mmCP_MQD_CONTROL); 3030 + mqd->queue_state.cp_mqd_control &= ~CP_MQD_CONTROL__VMID_MASK; 3031 + 3032 + /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */ 3033 + hqd_gpu_addr = ring->gpu_addr >> 8; 3034 + mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr; 3035 + mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr); 3036 + 3037 + /* set up the HQD, this is similar to CP_RB0_CNTL */ 3038 + mqd->queue_state.cp_hqd_pq_control = RREG32(mmCP_HQD_PQ_CONTROL); 3039 + mqd->queue_state.cp_hqd_pq_control &= 3040 + ~(CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK | 3041 + CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE_MASK); 3042 + 3043 + mqd->queue_state.cp_hqd_pq_control |= 3044 + order_base_2(ring->ring_size / 8); 3045 + mqd->queue_state.cp_hqd_pq_control |= 3046 + (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8); 3047 + #ifdef __BIG_ENDIAN 3048 + mqd->queue_state.cp_hqd_pq_control |= 3049 + 2 << CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT; 3050 + #endif 3051 + mqd->queue_state.cp_hqd_pq_control &= 3052 + ~(CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK | 3053 + CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP_MASK | 3054 + CP_HQD_PQ_CONTROL__PQ_VOLATILE_MASK); 3055 + mqd->queue_state.cp_hqd_pq_control |= 3056 + CP_HQD_PQ_CONTROL__PRIV_STATE_MASK | 3057 + CP_HQD_PQ_CONTROL__KMD_QUEUE_MASK; /* assuming kernel queue control */ 3058 + 3059 + /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */ 3060 + wb_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); 3061 + mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc; 3062 + mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff; 3063 + 3064 + /* set the wb address wether it's enabled or not */ 3065 + wb_gpu_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); 3066 + mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc; 3067 + mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi = 3068 + upper_32_bits(wb_gpu_addr) & 0xffff; 3069 + 3070 + /* enable the doorbell if requested */ 3071 + if (ring->use_doorbell) { 3072 + mqd->queue_state.cp_hqd_pq_doorbell_control = 3073 + RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); 3074 + mqd->queue_state.cp_hqd_pq_doorbell_control &= 3075 + ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK; 3076 + mqd->queue_state.cp_hqd_pq_doorbell_control |= 3077 + (ring->doorbell_index << 3078 + CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT); 3079 + mqd->queue_state.cp_hqd_pq_doorbell_control |= 3080 + CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3081 + mqd->queue_state.cp_hqd_pq_doorbell_control &= 3082 + ~(CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SOURCE_MASK | 3083 + CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_HIT_MASK); 3084 + 3085 + } else { 3086 + mqd->queue_state.cp_hqd_pq_doorbell_control = 0; 3087 + } 3088 + 3089 + /* read and write pointers, similar to CP_RB0_WPTR/_RPTR */ 3090 + ring->wptr = 0; 3091 + mqd->queue_state.cp_hqd_pq_wptr = lower_32_bits(ring->wptr); 3092 + mqd->queue_state.cp_hqd_pq_rptr = RREG32(mmCP_HQD_PQ_RPTR); 3093 + 3094 + /* set the vmid for the queue */ 3095 + mqd->queue_state.cp_hqd_vmid = 0; 3096 + 3097 + /* activate the queue */ 3098 + mqd->queue_state.cp_hqd_active = 1; 3099 + } 3100 + 3101 + static int gfx_v7_0_mqd_commit(struct amdgpu_device *adev, 3102 + struct bonaire_mqd *mqd) 3103 + { 3104 + u32 tmp; 3105 + 3106 + /* disable wptr polling */ 3107 + tmp = RREG32(mmCP_PQ_WPTR_POLL_CNTL); 3108 + tmp = REG_SET_FIELD(tmp, CP_PQ_WPTR_POLL_CNTL, EN, 0); 3109 + WREG32(mmCP_PQ_WPTR_POLL_CNTL, tmp); 3110 + 3111 + /* program MQD field to HW */ 3112 + WREG32(mmCP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr); 3113 + WREG32(mmCP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi); 3114 + WREG32(mmCP_MQD_CONTROL, mqd->queue_state.cp_mqd_control); 3115 + WREG32(mmCP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base); 3116 + WREG32(mmCP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi); 3117 + WREG32(mmCP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control); 3118 + WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr); 3119 + WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI, mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi); 3120 + WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR, mqd->queue_state.cp_hqd_pq_rptr_report_addr); 3121 + WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI, mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi); 3122 + WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->queue_state.cp_hqd_pq_doorbell_control); 3123 + WREG32(mmCP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 3124 + WREG32(mmCP_HQD_VMID, mqd->queue_state.cp_hqd_vmid); 3125 + 3126 + /* activate the HQD */ 3127 + WREG32(mmCP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); 3128 + 3129 + return 0; 3130 + } 3131 + 3132 + static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id) 3133 + { 3134 + int r; 3135 + u64 mqd_gpu_addr; 3136 + struct bonaire_mqd *mqd; 3137 + struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id]; 3138 + 3139 + if (ring->mqd_obj == NULL) { 3140 + r = amdgpu_bo_create(adev, 3141 + sizeof(struct bonaire_mqd), 3142 + PAGE_SIZE, true, 3143 + AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, 3144 + &ring->mqd_obj); 3145 + if (r) { 3146 + dev_warn(adev->dev, "(%d) create MQD bo failed\n", r); 3147 + return r; 3148 + } 3149 + } 3150 + 3151 + r = amdgpu_bo_reserve(ring->mqd_obj, false); 3152 + if (unlikely(r != 0)) 3153 + goto out; 3154 + 3155 + r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT, 3156 + &mqd_gpu_addr); 3157 + if (r) { 3158 + dev_warn(adev->dev, "(%d) pin MQD bo failed\n", r); 3159 + goto out_unreserve; 3160 + } 3161 + r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd); 3162 + if (r) { 3163 + dev_warn(adev->dev, "(%d) map MQD bo failed\n", r); 3164 + goto out_unreserve; 3165 + } 3166 + 3167 + mutex_lock(&adev->srbm_mutex); 3168 + cik_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); 3169 + 3170 + gfx_v7_0_mqd_init(adev, mqd, mqd_gpu_addr, ring); 3171 + gfx_v7_0_mqd_deactivate(adev); 3172 + gfx_v7_0_mqd_commit(adev, mqd); 3173 + 3174 + cik_srbm_select(adev, 0, 0, 0, 0); 3175 + mutex_unlock(&adev->srbm_mutex); 3176 + 3177 + amdgpu_bo_kunmap(ring->mqd_obj); 3178 + out_unreserve: 3179 + amdgpu_bo_unreserve(ring->mqd_obj); 3180 + out: 3181 + return 0; 3182 + } 3183 + 2947 3184 /** 2948 3185 * gfx_v7_0_cp_compute_resume - setup the compute queue registers 2949 3186 * ··· 3194 2957 { 3195 2958 int r, i, j; 3196 2959 u32 tmp; 3197 - bool use_doorbell = true; 3198 - u64 hqd_gpu_addr; 3199 - u64 mqd_gpu_addr; 3200 - u64 eop_gpu_addr; 3201 - u64 wb_gpu_addr; 3202 - u32 *buf; 3203 - struct bonaire_mqd *mqd; 3204 2960 struct amdgpu_ring *ring; 3205 2961 3206 2962 /* fix up chicken bits */ ··· 3202 2972 WREG32(mmCP_CPF_DEBUG, tmp); 3203 2973 3204 2974 /* init the pipes */ 3205 - mutex_lock(&adev->srbm_mutex); 3206 - for (i = 0; i < (adev->gfx.mec.num_pipe * adev->gfx.mec.num_mec); i++) { 3207 - int me = (i < 4) ? 1 : 2; 3208 - int pipe = (i < 4) ? i : (i - 4); 2975 + for (i = 0; i < adev->gfx.mec.num_mec; i++) 2976 + for (j = 0; j < adev->gfx.mec.num_pipe; j++) 2977 + gfx_v7_0_compute_pipe_init(adev, i, j); 3209 2978 3210 - eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + (i * GFX7_MEC_HPD_SIZE * 2); 3211 - 3212 - cik_srbm_select(adev, me, pipe, 0, 0); 3213 - 3214 - /* write the EOP addr */ 3215 - WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); 3216 - WREG32(mmCP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8); 3217 - 3218 - /* set the VMID assigned */ 3219 - WREG32(mmCP_HPD_EOP_VMID, 0); 3220 - 3221 - /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ 3222 - tmp = RREG32(mmCP_HPD_EOP_CONTROL); 3223 - tmp &= ~CP_HPD_EOP_CONTROL__EOP_SIZE_MASK; 3224 - tmp |= order_base_2(GFX7_MEC_HPD_SIZE / 8); 3225 - WREG32(mmCP_HPD_EOP_CONTROL, tmp); 3226 - } 3227 - cik_srbm_select(adev, 0, 0, 0, 0); 3228 - mutex_unlock(&adev->srbm_mutex); 3229 - 3230 - /* init the queues. Just two for now. */ 2979 + /* init the queues */ 3231 2980 for (i = 0; i < adev->gfx.num_compute_rings; i++) { 3232 - ring = &adev->gfx.compute_ring[i]; 3233 - 3234 - if (ring->mqd_obj == NULL) { 3235 - r = amdgpu_bo_create(adev, 3236 - sizeof(struct bonaire_mqd), 3237 - PAGE_SIZE, true, 3238 - AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, 3239 - &ring->mqd_obj); 3240 - if (r) { 3241 - dev_warn(adev->dev, "(%d) create MQD bo failed\n", r); 3242 - return r; 3243 - } 3244 - } 3245 - 3246 - r = amdgpu_bo_reserve(ring->mqd_obj, false); 3247 - if (unlikely(r != 0)) { 3248 - gfx_v7_0_cp_compute_fini(adev); 3249 - return r; 3250 - } 3251 - r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT, 3252 - &mqd_gpu_addr); 2981 + r = gfx_v7_0_compute_queue_init(adev, i); 3253 2982 if (r) { 3254 - dev_warn(adev->dev, "(%d) pin MQD bo failed\n", r); 3255 2983 gfx_v7_0_cp_compute_fini(adev); 3256 2984 return r; 3257 2985 } 3258 - r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&buf); 3259 - if (r) { 3260 - dev_warn(adev->dev, "(%d) map MQD bo failed\n", r); 3261 - gfx_v7_0_cp_compute_fini(adev); 3262 - return r; 3263 - } 3264 - 3265 - /* init the mqd struct */ 3266 - memset(buf, 0, sizeof(struct bonaire_mqd)); 3267 - 3268 - mqd = (struct bonaire_mqd *)buf; 3269 - mqd->header = 0xC0310800; 3270 - mqd->static_thread_mgmt01[0] = 0xffffffff; 3271 - mqd->static_thread_mgmt01[1] = 0xffffffff; 3272 - mqd->static_thread_mgmt23[0] = 0xffffffff; 3273 - mqd->static_thread_mgmt23[1] = 0xffffffff; 3274 - 3275 - mutex_lock(&adev->srbm_mutex); 3276 - cik_srbm_select(adev, ring->me, 3277 - ring->pipe, 3278 - ring->queue, 0); 3279 - 3280 - /* disable wptr polling */ 3281 - tmp = RREG32(mmCP_PQ_WPTR_POLL_CNTL); 3282 - tmp &= ~CP_PQ_WPTR_POLL_CNTL__EN_MASK; 3283 - WREG32(mmCP_PQ_WPTR_POLL_CNTL, tmp); 3284 - 3285 - /* enable doorbell? */ 3286 - mqd->queue_state.cp_hqd_pq_doorbell_control = 3287 - RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); 3288 - if (use_doorbell) 3289 - mqd->queue_state.cp_hqd_pq_doorbell_control |= CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3290 - else 3291 - mqd->queue_state.cp_hqd_pq_doorbell_control &= ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3292 - WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 3293 - mqd->queue_state.cp_hqd_pq_doorbell_control); 3294 - 3295 - /* disable the queue if it's active */ 3296 - mqd->queue_state.cp_hqd_dequeue_request = 0; 3297 - mqd->queue_state.cp_hqd_pq_rptr = 0; 3298 - mqd->queue_state.cp_hqd_pq_wptr= 0; 3299 - if (RREG32(mmCP_HQD_ACTIVE) & 1) { 3300 - WREG32(mmCP_HQD_DEQUEUE_REQUEST, 1); 3301 - for (j = 0; j < adev->usec_timeout; j++) { 3302 - if (!(RREG32(mmCP_HQD_ACTIVE) & 1)) 3303 - break; 3304 - udelay(1); 3305 - } 3306 - WREG32(mmCP_HQD_DEQUEUE_REQUEST, mqd->queue_state.cp_hqd_dequeue_request); 3307 - WREG32(mmCP_HQD_PQ_RPTR, mqd->queue_state.cp_hqd_pq_rptr); 3308 - WREG32(mmCP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 3309 - } 3310 - 3311 - /* set the pointer to the MQD */ 3312 - mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc; 3313 - mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr); 3314 - WREG32(mmCP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr); 3315 - WREG32(mmCP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi); 3316 - /* set MQD vmid to 0 */ 3317 - mqd->queue_state.cp_mqd_control = RREG32(mmCP_MQD_CONTROL); 3318 - mqd->queue_state.cp_mqd_control &= ~CP_MQD_CONTROL__VMID_MASK; 3319 - WREG32(mmCP_MQD_CONTROL, mqd->queue_state.cp_mqd_control); 3320 - 3321 - /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */ 3322 - hqd_gpu_addr = ring->gpu_addr >> 8; 3323 - mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr; 3324 - mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr); 3325 - WREG32(mmCP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base); 3326 - WREG32(mmCP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi); 3327 - 3328 - /* set up the HQD, this is similar to CP_RB0_CNTL */ 3329 - mqd->queue_state.cp_hqd_pq_control = RREG32(mmCP_HQD_PQ_CONTROL); 3330 - mqd->queue_state.cp_hqd_pq_control &= 3331 - ~(CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK | 3332 - CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE_MASK); 3333 - 3334 - mqd->queue_state.cp_hqd_pq_control |= 3335 - order_base_2(ring->ring_size / 8); 3336 - mqd->queue_state.cp_hqd_pq_control |= 3337 - (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8); 3338 - #ifdef __BIG_ENDIAN 3339 - mqd->queue_state.cp_hqd_pq_control |= 3340 - 2 << CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT; 3341 - #endif 3342 - mqd->queue_state.cp_hqd_pq_control &= 3343 - ~(CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK | 3344 - CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP_MASK | 3345 - CP_HQD_PQ_CONTROL__PQ_VOLATILE_MASK); 3346 - mqd->queue_state.cp_hqd_pq_control |= 3347 - CP_HQD_PQ_CONTROL__PRIV_STATE_MASK | 3348 - CP_HQD_PQ_CONTROL__KMD_QUEUE_MASK; /* assuming kernel queue control */ 3349 - WREG32(mmCP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control); 3350 - 3351 - /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */ 3352 - wb_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4); 3353 - mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc; 3354 - mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff; 3355 - WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr); 3356 - WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI, 3357 - mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi); 3358 - 3359 - /* set the wb address wether it's enabled or not */ 3360 - wb_gpu_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4); 3361 - mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc; 3362 - mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi = 3363 - upper_32_bits(wb_gpu_addr) & 0xffff; 3364 - WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR, 3365 - mqd->queue_state.cp_hqd_pq_rptr_report_addr); 3366 - WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI, 3367 - mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi); 3368 - 3369 - /* enable the doorbell if requested */ 3370 - if (use_doorbell) { 3371 - mqd->queue_state.cp_hqd_pq_doorbell_control = 3372 - RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); 3373 - mqd->queue_state.cp_hqd_pq_doorbell_control &= 3374 - ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK; 3375 - mqd->queue_state.cp_hqd_pq_doorbell_control |= 3376 - (ring->doorbell_index << 3377 - CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT); 3378 - mqd->queue_state.cp_hqd_pq_doorbell_control |= 3379 - CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3380 - mqd->queue_state.cp_hqd_pq_doorbell_control &= 3381 - ~(CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SOURCE_MASK | 3382 - CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_HIT_MASK); 3383 - 3384 - } else { 3385 - mqd->queue_state.cp_hqd_pq_doorbell_control = 0; 3386 - } 3387 - WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 3388 - mqd->queue_state.cp_hqd_pq_doorbell_control); 3389 - 3390 - /* read and write pointers, similar to CP_RB0_WPTR/_RPTR */ 3391 - ring->wptr = 0; 3392 - mqd->queue_state.cp_hqd_pq_wptr = lower_32_bits(ring->wptr); 3393 - WREG32(mmCP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 3394 - mqd->queue_state.cp_hqd_pq_rptr = RREG32(mmCP_HQD_PQ_RPTR); 3395 - 3396 - /* set the vmid for the queue */ 3397 - mqd->queue_state.cp_hqd_vmid = 0; 3398 - WREG32(mmCP_HQD_VMID, mqd->queue_state.cp_hqd_vmid); 3399 - 3400 - /* activate the queue */ 3401 - mqd->queue_state.cp_hqd_active = 1; 3402 - WREG32(mmCP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); 3403 - 3404 - cik_srbm_select(adev, 0, 0, 0, 0); 3405 - mutex_unlock(&adev->srbm_mutex); 3406 - 3407 - amdgpu_bo_kunmap(ring->mqd_obj); 3408 - amdgpu_bo_unreserve(ring->mqd_obj); 3409 - 3410 - ring->ready = true; 3411 2986 } 3412 2987 3413 2988 gfx_v7_0_cp_compute_enable(adev, true); 3414 2989 3415 2990 for (i = 0; i < adev->gfx.num_compute_rings; i++) { 3416 2991 ring = &adev->gfx.compute_ring[i]; 3417 - 2992 + ring->ready = true; 3418 2993 r = amdgpu_ring_test_ring(ring); 3419 2994 if (r) 3420 2995 ring->ready = false;
+34 -44
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
··· 4772 4772 return r; 4773 4773 } 4774 4774 4775 + static int gfx_v8_0_deactivate_hqd(struct amdgpu_device *adev, u32 req) 4776 + { 4777 + int i, r = 0; 4778 + 4779 + if (RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK) { 4780 + WREG32_FIELD(CP_HQD_DEQUEUE_REQUEST, DEQUEUE_REQ, req); 4781 + for (i = 0; i < adev->usec_timeout; i++) { 4782 + if (!(RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK)) 4783 + break; 4784 + udelay(1); 4785 + } 4786 + if (i == adev->usec_timeout) 4787 + r = -ETIMEDOUT; 4788 + } 4789 + WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0); 4790 + WREG32(mmCP_HQD_PQ_RPTR, 0); 4791 + WREG32(mmCP_HQD_PQ_WPTR, 0); 4792 + 4793 + return r; 4794 + } 4795 + 4775 4796 static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring) 4776 4797 { 4777 4798 struct amdgpu_device *adev = ring->adev; 4778 4799 struct vi_mqd *mqd = ring->mqd_ptr; 4779 4800 uint64_t hqd_gpu_addr, wb_gpu_addr, eop_base_addr; 4780 4801 uint32_t tmp; 4802 + 4803 + /* init the mqd struct */ 4804 + memset(mqd, 0, sizeof(struct vi_mqd)); 4781 4805 4782 4806 mqd->header = 0xC0310800; 4783 4807 mqd->compute_pipelinestat_enable = 0x00000001; ··· 4829 4805 ring->use_doorbell ? 1 : 0); 4830 4806 4831 4807 mqd->cp_hqd_pq_doorbell_control = tmp; 4832 - 4833 - /* disable the queue if it's active */ 4834 - mqd->cp_hqd_dequeue_request = 0; 4835 - mqd->cp_hqd_pq_rptr = 0; 4836 - mqd->cp_hqd_pq_wptr = 0; 4837 4808 4838 4809 /* set the pointer to the MQD */ 4839 4810 mqd->cp_mqd_base_addr_lo = ring->mqd_gpu_addr & 0xfffffffc; ··· 4919 4900 return 0; 4920 4901 } 4921 4902 4922 - static int gfx_v8_0_kiq_init_register(struct amdgpu_ring *ring) 4903 + static int gfx_v8_0_mqd_commit(struct amdgpu_ring *ring) 4923 4904 { 4924 4905 struct amdgpu_device *adev = ring->adev; 4925 4906 struct vi_mqd *mqd = ring->mqd_ptr; 4926 - int j; 4927 4907 4928 4908 /* disable wptr polling */ 4929 4909 WREG32_FIELD(CP_PQ_WPTR_POLL_CNTL, EN, 0); ··· 4936 4918 /* enable doorbell? */ 4937 4919 WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->cp_hqd_pq_doorbell_control); 4938 4920 4939 - /* disable the queue if it's active */ 4940 - if (RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK) { 4941 - WREG32(mmCP_HQD_DEQUEUE_REQUEST, 1); 4942 - for (j = 0; j < adev->usec_timeout; j++) { 4943 - if (!(RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK)) 4944 - break; 4945 - udelay(1); 4946 - } 4947 - WREG32(mmCP_HQD_DEQUEUE_REQUEST, mqd->cp_hqd_dequeue_request); 4948 - WREG32(mmCP_HQD_PQ_RPTR, mqd->cp_hqd_pq_rptr); 4949 - WREG32(mmCP_HQD_PQ_WPTR, mqd->cp_hqd_pq_wptr); 4950 - } 4921 + /* set pq read/write pointers */ 4922 + WREG32(mmCP_HQD_DEQUEUE_REQUEST, mqd->cp_hqd_dequeue_request); 4923 + WREG32(mmCP_HQD_PQ_RPTR, mqd->cp_hqd_pq_rptr); 4924 + WREG32(mmCP_HQD_PQ_WPTR, mqd->cp_hqd_pq_wptr); 4951 4925 4952 4926 /* set the pointer to the MQD */ 4953 4927 WREG32(mmCP_MQD_BASE_ADDR, mqd->cp_mqd_base_addr_lo); ··· 4965 4955 WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->cp_hqd_pq_wptr_poll_addr_lo); 4966 4956 WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI, mqd->cp_hqd_pq_wptr_poll_addr_hi); 4967 4957 4958 + /* enable the doorbell if requested */ 4968 4959 WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->cp_hqd_pq_doorbell_control); 4969 4960 4970 4961 /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */ ··· 5000 4989 amdgpu_ring_clear_ring(ring); 5001 4990 mutex_lock(&adev->srbm_mutex); 5002 4991 vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); 5003 - gfx_v8_0_kiq_init_register(ring); 4992 + gfx_v8_0_deactivate_hqd(adev, 1); 4993 + gfx_v8_0_mqd_commit(ring); 5004 4994 vi_srbm_select(adev, 0, 0, 0, 0); 5005 4995 mutex_unlock(&adev->srbm_mutex); 5006 4996 } else { 5007 - memset((void *)mqd, 0, sizeof(*mqd)); 5008 4997 mutex_lock(&adev->srbm_mutex); 5009 4998 vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); 5010 4999 gfx_v8_0_mqd_init(ring); 5011 - gfx_v8_0_kiq_init_register(ring); 5000 + gfx_v8_0_deactivate_hqd(adev, 1); 5001 + gfx_v8_0_mqd_commit(ring); 5012 5002 vi_srbm_select(adev, 0, 0, 0, 0); 5013 5003 mutex_unlock(&adev->srbm_mutex); 5014 5004 ··· 5027 5015 int mqd_idx = ring - &adev->gfx.compute_ring[0]; 5028 5016 5029 5017 if (!adev->gfx.in_reset && !adev->gfx.in_suspend) { 5030 - memset((void *)mqd, 0, sizeof(*mqd)); 5031 5018 mutex_lock(&adev->srbm_mutex); 5032 5019 vi_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0); 5033 5020 gfx_v8_0_mqd_init(ring); ··· 5329 5318 adev->gfx.srbm_soft_reset = 0; 5330 5319 return false; 5331 5320 } 5332 - } 5333 - 5334 - static int gfx_v8_0_deactivate_hqd(struct amdgpu_device *adev, u32 req) 5335 - { 5336 - int i, r = 0; 5337 - 5338 - if (RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK) { 5339 - WREG32_FIELD(CP_HQD_DEQUEUE_REQUEST, DEQUEUE_REQ, req); 5340 - for (i = 0; i < adev->usec_timeout; i++) { 5341 - if (!(RREG32(mmCP_HQD_ACTIVE) & CP_HQD_ACTIVE__ACTIVE_MASK)) 5342 - break; 5343 - udelay(1); 5344 - } 5345 - if (i == adev->usec_timeout) 5346 - r = -ETIMEDOUT; 5347 - } 5348 - WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0); 5349 - WREG32(mmCP_HQD_PQ_RPTR, 0); 5350 - WREG32(mmCP_HQD_PQ_WPTR, 0); 5351 - 5352 - return r; 5353 5321 } 5354 5322 5355 5323 static int gfx_v8_0_pre_soft_reset(void *handle)