aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
diff options
context:
space:
mode:
authorAndres Rodriguez <andresx7@gmail.com>2017-04-12 17:19:54 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-05-31 16:48:46 -0400
commit34130fb1493c91d50b04daaeb25e82eecc4483c6 (patch)
tree4e812b3923272a80312ab061c4eab446048abde2 /drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
parent268cb4c7dff0aac96b1c5d596b321aa197d31360 (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c439
1 files changed, 237 insertions, 202 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index 3372ad10eb5a..7754958cc643 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -2944,247 +2944,282 @@ struct bonaire_mqd
2944 u32 interrupt_queue[64]; 2944 u32 interrupt_queue[64];
2945}; 2945};
2946 2946
2947/** 2947static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev, int me, int pipe)
2948 * gfx_v7_0_cp_compute_resume - setup the compute queue registers
2949 *
2950 * @adev: amdgpu_device pointer
2951 *
2952 * Program the compute queues and test them to make sure they
2953 * are working.
2954 * Returns 0 for success, error for failure.
2955 */
2956static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev)
2957{ 2948{
2958 int r, i, j;
2959 u32 tmp;
2960 bool use_doorbell = true;
2961 u64 hqd_gpu_addr;
2962 u64 mqd_gpu_addr;
2963 u64 eop_gpu_addr; 2949 u64 eop_gpu_addr;
2964 u64 wb_gpu_addr; 2950 u32 tmp;
2965 u32 *buf; 2951 size_t eop_offset = me * pipe * GFX7_MEC_HPD_SIZE * 2;
2966 struct bonaire_mqd *mqd;
2967 struct amdgpu_ring *ring;
2968
2969 /* fix up chicken bits */
2970 tmp = RREG32(mmCP_CPF_DEBUG);
2971 tmp |= (1 << 23);
2972 WREG32(mmCP_CPF_DEBUG, tmp);
2973 2952
2974 /* init the pipes */
2975 mutex_lock(&adev->srbm_mutex); 2953 mutex_lock(&adev->srbm_mutex);
2976 for (i = 0; i < (adev->gfx.mec.num_pipe * adev->gfx.mec.num_mec); i++) { 2954 eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + eop_offset;
2977 int me = (i < 4) ? 1 : 2;
2978 int pipe = (i < 4) ? i : (i - 4);
2979 2955
2980 eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + (i * GFX7_MEC_HPD_SIZE * 2); 2956 cik_srbm_select(adev, me, pipe, 0, 0);
2981 2957
2982 cik_srbm_select(adev, me, pipe, 0, 0); 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);
2983 2961
2984 /* write the EOP addr */ 2962 /* set the VMID assigned */
2985 WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); 2963 WREG32(mmCP_HPD_EOP_VMID, 0);
2986 WREG32(mmCP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8);
2987 2964
2988 /* set the VMID assigned */ 2965 /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
2989 WREG32(mmCP_HPD_EOP_VMID, 0); 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);
2990 2970
2991 /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
2992 tmp = RREG32(mmCP_HPD_EOP_CONTROL);
2993 tmp &= ~CP_HPD_EOP_CONTROL__EOP_SIZE_MASK;
2994 tmp |= order_base_2(GFX7_MEC_HPD_SIZE / 8);
2995 WREG32(mmCP_HPD_EOP_CONTROL, tmp);
2996 }
2997 cik_srbm_select(adev, 0, 0, 0, 0); 2971 cik_srbm_select(adev, 0, 0, 0, 0);
2998 mutex_unlock(&adev->srbm_mutex); 2972 mutex_unlock(&adev->srbm_mutex);
2973}
2999 2974
3000 /* init the queues. Just two for now. */ 2975static int gfx_v7_0_mqd_deactivate(struct amdgpu_device *adev)
3001 for (i = 0; i < adev->gfx.num_compute_rings; i++) { 2976{
3002 ring = &adev->gfx.compute_ring[i]; 2977 int i;
3003 2978
3004 if (ring->mqd_obj == NULL) { 2979 /* disable the queue if it's active */
3005 r = amdgpu_bo_create(adev, 2980 if (RREG32(mmCP_HQD_ACTIVE) & 1) {
3006 sizeof(struct bonaire_mqd), 2981 WREG32(mmCP_HQD_DEQUEUE_REQUEST, 1);
3007 PAGE_SIZE, true, 2982 for (i = 0; i < adev->usec_timeout; i++) {
3008 AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, 2983 if (!(RREG32(mmCP_HQD_ACTIVE) & 1))
3009 &ring->mqd_obj); 2984 break;
3010 if (r) { 2985 udelay(1);
3011 dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
3012 return r;
3013 }
3014 } 2986 }
3015 2987
3016 r = amdgpu_bo_reserve(ring->mqd_obj, false); 2988 if (i == adev->usec_timeout)
3017 if (unlikely(r != 0)) { 2989 return -ETIMEDOUT;
3018 gfx_v7_0_cp_compute_fini(adev);
3019 return r;
3020 }
3021 r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT,
3022 &mqd_gpu_addr);
3023 if (r) {
3024 dev_warn(adev->dev, "(%d) pin MQD bo failed\n", r);
3025 gfx_v7_0_cp_compute_fini(adev);
3026 return r;
3027 }
3028 r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&buf);
3029 if (r) {
3030 dev_warn(adev->dev, "(%d) map MQD bo failed\n", r);
3031 gfx_v7_0_cp_compute_fini(adev);
3032 return r;
3033 }
3034 2990
3035 /* init the mqd struct */ 2991 WREG32(mmCP_HQD_DEQUEUE_REQUEST, 0);
3036 memset(buf, 0, sizeof(struct bonaire_mqd)); 2992 WREG32(mmCP_HQD_PQ_RPTR, 0);
2993 WREG32(mmCP_HQD_PQ_WPTR, 0);
2994 }
3037 2995
3038 mqd = (struct bonaire_mqd *)buf; 2996 return 0;
3039 mqd->header = 0xC0310800; 2997}
3040 mqd->static_thread_mgmt01[0] = 0xffffffff;
3041 mqd->static_thread_mgmt01[1] = 0xffffffff;
3042 mqd->static_thread_mgmt23[0] = 0xffffffff;
3043 mqd->static_thread_mgmt23[1] = 0xffffffff;
3044 2998
3045 mutex_lock(&adev->srbm_mutex); 2999static void gfx_v7_0_mqd_init(struct amdgpu_device *adev,
3046 cik_srbm_select(adev, ring->me, 3000 struct bonaire_mqd *mqd,
3047 ring->pipe, 3001 uint64_t mqd_gpu_addr,
3048 ring->queue, 0); 3002 struct amdgpu_ring *ring)
3003{
3004 u64 hqd_gpu_addr;
3005 u64 wb_gpu_addr;
3049 3006
3050 /* disable wptr polling */ 3007 /* init the mqd struct */
3051 tmp = RREG32(mmCP_PQ_WPTR_POLL_CNTL); 3008 memset(mqd, 0, sizeof(struct bonaire_mqd));
3052 tmp &= ~CP_PQ_WPTR_POLL_CNTL__EN_MASK;
3053 WREG32(mmCP_PQ_WPTR_POLL_CNTL, tmp);
3054 3009
3055 /* enable doorbell? */ 3010 mqd->header = 0xC0310800;
3056 mqd->queue_state.cp_hqd_pq_doorbell_control = 3011 mqd->static_thread_mgmt01[0] = 0xffffffff;
3057 RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL); 3012 mqd->static_thread_mgmt01[1] = 0xffffffff;
3058 if (use_doorbell) 3013 mqd->static_thread_mgmt23[0] = 0xffffffff;
3059 mqd->queue_state.cp_hqd_pq_doorbell_control |= CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK; 3014 mqd->static_thread_mgmt23[1] = 0xffffffff;
3060 else
3061 mqd->queue_state.cp_hqd_pq_doorbell_control &= ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK;
3062 WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL,
3063 mqd->queue_state.cp_hqd_pq_doorbell_control);
3064
3065 /* disable the queue if it's active */
3066 mqd->queue_state.cp_hqd_dequeue_request = 0;
3067 mqd->queue_state.cp_hqd_pq_rptr = 0;
3068 mqd->queue_state.cp_hqd_pq_wptr= 0;
3069 if (RREG32(mmCP_HQD_ACTIVE) & 1) {
3070 WREG32(mmCP_HQD_DEQUEUE_REQUEST, 1);
3071 for (j = 0; j < adev->usec_timeout; j++) {
3072 if (!(RREG32(mmCP_HQD_ACTIVE) & 1))
3073 break;
3074 udelay(1);
3075 }
3076 WREG32(mmCP_HQD_DEQUEUE_REQUEST, mqd->queue_state.cp_hqd_dequeue_request);
3077 WREG32(mmCP_HQD_PQ_RPTR, mqd->queue_state.cp_hqd_pq_rptr);
3078 WREG32(mmCP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
3079 }
3080 3015
3081 /* set the pointer to the MQD */ 3016 /* enable doorbell? */
3082 mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc; 3017 mqd->queue_state.cp_hqd_pq_doorbell_control =
3083 mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr); 3018 RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL);
3084 WREG32(mmCP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr); 3019 if (ring->use_doorbell)
3085 WREG32(mmCP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi); 3020 mqd->queue_state.cp_hqd_pq_doorbell_control |= CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK;
3086 /* set MQD vmid to 0 */ 3021 else
3087 mqd->queue_state.cp_mqd_control = RREG32(mmCP_MQD_CONTROL); 3022 mqd->queue_state.cp_hqd_pq_doorbell_control &= ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK;
3088 mqd->queue_state.cp_mqd_control &= ~CP_MQD_CONTROL__VMID_MASK; 3023
3089 WREG32(mmCP_MQD_CONTROL, mqd->queue_state.cp_mqd_control); 3024 /* set the pointer to the MQD */
3090 3025 mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc;
3091 /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */ 3026 mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr);
3092 hqd_gpu_addr = ring->gpu_addr >> 8; 3027
3093 mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr; 3028 /* set MQD vmid to 0 */
3094 mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr); 3029 mqd->queue_state.cp_mqd_control = RREG32(mmCP_MQD_CONTROL);
3095 WREG32(mmCP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base); 3030 mqd->queue_state.cp_mqd_control &= ~CP_MQD_CONTROL__VMID_MASK;
3096 WREG32(mmCP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi); 3031
3097 3032 /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */
3098 /* set up the HQD, this is similar to CP_RB0_CNTL */ 3033 hqd_gpu_addr = ring->gpu_addr >> 8;
3099 mqd->queue_state.cp_hqd_pq_control = RREG32(mmCP_HQD_PQ_CONTROL); 3034 mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr;
3100 mqd->queue_state.cp_hqd_pq_control &= 3035 mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr);
3101 ~(CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK | 3036
3102 CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE_MASK); 3037 /* set up the HQD, this is similar to CP_RB0_CNTL */
3103 3038 mqd->queue_state.cp_hqd_pq_control = RREG32(mmCP_HQD_PQ_CONTROL);
3104 mqd->queue_state.cp_hqd_pq_control |= 3039 mqd->queue_state.cp_hqd_pq_control &=
3105 order_base_2(ring->ring_size / 8); 3040 ~(CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK |
3106 mqd->queue_state.cp_hqd_pq_control |= 3041 CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE_MASK);
3107 (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8); 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);
3108#ifdef __BIG_ENDIAN 3047#ifdef __BIG_ENDIAN
3109 mqd->queue_state.cp_hqd_pq_control |= 3048 mqd->queue_state.cp_hqd_pq_control |=
3110 2 << CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT; 3049 2 << CP_HQD_PQ_CONTROL__ENDIAN_SWAP__SHIFT;
3111#endif 3050#endif
3112 mqd->queue_state.cp_hqd_pq_control &= 3051 mqd->queue_state.cp_hqd_pq_control &=
3113 ~(CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK | 3052 ~(CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK |
3114 CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP_MASK | 3053 CP_HQD_PQ_CONTROL__ROQ_PQ_IB_FLIP_MASK |
3115 CP_HQD_PQ_CONTROL__PQ_VOLATILE_MASK); 3054 CP_HQD_PQ_CONTROL__PQ_VOLATILE_MASK);
3116 mqd->queue_state.cp_hqd_pq_control |= 3055 mqd->queue_state.cp_hqd_pq_control |=
3117 CP_HQD_PQ_CONTROL__PRIV_STATE_MASK | 3056 CP_HQD_PQ_CONTROL__PRIV_STATE_MASK |
3118 CP_HQD_PQ_CONTROL__KMD_QUEUE_MASK; /* assuming kernel queue control */ 3057 CP_HQD_PQ_CONTROL__KMD_QUEUE_MASK; /* assuming kernel queue control */
3119 WREG32(mmCP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control);
3120
3121 /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */
3122 wb_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
3123 mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc;
3124 mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff;
3125 WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr);
3126 WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI,
3127 mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi);
3128
3129 /* set the wb address wether it's enabled or not */
3130 wb_gpu_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4);
3131 mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc;
3132 mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi =
3133 upper_32_bits(wb_gpu_addr) & 0xffff;
3134 WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR,
3135 mqd->queue_state.cp_hqd_pq_rptr_report_addr);
3136 WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI,
3137 mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi);
3138
3139 /* enable the doorbell if requested */
3140 if (use_doorbell) {
3141 mqd->queue_state.cp_hqd_pq_doorbell_control =
3142 RREG32(mmCP_HQD_PQ_DOORBELL_CONTROL);
3143 mqd->queue_state.cp_hqd_pq_doorbell_control &=
3144 ~CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET_MASK;
3145 mqd->queue_state.cp_hqd_pq_doorbell_control |=
3146 (ring->doorbell_index <<
3147 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_OFFSET__SHIFT);
3148 mqd->queue_state.cp_hqd_pq_doorbell_control |=
3149 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_EN_MASK;
3150 mqd->queue_state.cp_hqd_pq_doorbell_control &=
3151 ~(CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_SOURCE_MASK |
3152 CP_HQD_PQ_DOORBELL_CONTROL__DOORBELL_HIT_MASK);
3153 3058
3154 } else { 3059 /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */
3155 mqd->queue_state.cp_hqd_pq_doorbell_control = 0; 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
3101static 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
3132static 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;
3156 } 3148 }
3157 WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, 3149 }
3158 mqd->queue_state.cp_hqd_pq_doorbell_control);
3159 3150
3160 /* read and write pointers, similar to CP_RB0_WPTR/_RPTR */ 3151 r = amdgpu_bo_reserve(ring->mqd_obj, false);
3161 ring->wptr = 0; 3152 if (unlikely(r != 0))
3162 mqd->queue_state.cp_hqd_pq_wptr = lower_32_bits(ring->wptr); 3153 goto out;
3163 WREG32(mmCP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr);
3164 mqd->queue_state.cp_hqd_pq_rptr = RREG32(mmCP_HQD_PQ_RPTR);
3165 3154
3166 /* set the vmid for the queue */ 3155 r = amdgpu_bo_pin(ring->mqd_obj, AMDGPU_GEM_DOMAIN_GTT,
3167 mqd->queue_state.cp_hqd_vmid = 0; 3156 &mqd_gpu_addr);
3168 WREG32(mmCP_HQD_VMID, mqd->queue_state.cp_hqd_vmid); 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 }
3169 3166
3170 /* activate the queue */ 3167 mutex_lock(&adev->srbm_mutex);
3171 mqd->queue_state.cp_hqd_active = 1; 3168 cik_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
3172 WREG32(mmCP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active);
3173 3169
3174 cik_srbm_select(adev, 0, 0, 0, 0); 3170 gfx_v7_0_mqd_init(adev, mqd, mqd_gpu_addr, ring);
3175 mutex_unlock(&adev->srbm_mutex); 3171 gfx_v7_0_mqd_deactivate(adev);
3172 gfx_v7_0_mqd_commit(adev, mqd);
3176 3173
3177 amdgpu_bo_kunmap(ring->mqd_obj); 3174 cik_srbm_select(adev, 0, 0, 0, 0);
3178 amdgpu_bo_unreserve(ring->mqd_obj); 3175 mutex_unlock(&adev->srbm_mutex);
3179 3176
3180 ring->ready = true; 3177 amdgpu_bo_kunmap(ring->mqd_obj);
3178out_unreserve:
3179 amdgpu_bo_unreserve(ring->mqd_obj);
3180out:
3181 return 0;
3182}
3183
3184/**
3185 * gfx_v7_0_cp_compute_resume - setup the compute queue registers
3186 *
3187 * @adev: amdgpu_device pointer
3188 *
3189 * Program the compute queues and test them to make sure they
3190 * are working.
3191 * Returns 0 for success, error for failure.
3192 */
3193static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev)
3194{
3195 int r, i, j;
3196 u32 tmp;
3197 struct amdgpu_ring *ring;
3198
3199 /* fix up chicken bits */
3200 tmp = RREG32(mmCP_CPF_DEBUG);
3201 tmp |= (1 << 23);
3202 WREG32(mmCP_CPF_DEBUG, tmp);
3203
3204 /* init the pipes */
3205 for (i = 0; i < adev->gfx.mec.num_mec; i++)
3206 for (j = 0; j < adev->gfx.mec.num_pipe; j++)
3207 gfx_v7_0_compute_pipe_init(adev, i, j);
3208
3209 /* init the queues */
3210 for (i = 0; i < adev->gfx.num_compute_rings; i++) {
3211 r = gfx_v7_0_compute_queue_init(adev, i);
3212 if (r) {
3213 gfx_v7_0_cp_compute_fini(adev);
3214 return r;
3215 }
3181 } 3216 }
3182 3217
3183 gfx_v7_0_cp_compute_enable(adev, true); 3218 gfx_v7_0_cp_compute_enable(adev, true);
3184 3219
3185 for (i = 0; i < adev->gfx.num_compute_rings; i++) { 3220 for (i = 0; i < adev->gfx.num_compute_rings; i++) {
3186 ring = &adev->gfx.compute_ring[i]; 3221 ring = &adev->gfx.compute_ring[i];
3187 3222 ring->ready = true;
3188 r = amdgpu_ring_test_ring(ring); 3223 r = amdgpu_ring_test_ring(ring);
3189 if (r) 3224 if (r)
3190 ring->ready = false; 3225 ring->ready = false;