#ifdef CONFIG_DRM_AMDGPU_CIK
 extern int amdgpu_cik_support;
 #endif
+extern int amdgpu_num_kcq;
 
 #define AMDGPU_VM_MAX_NUM_CTX                  4096
 #define AMDGPU_SG_THRESHOLD                    (256*1024*1024)
 
 
        amdgpu_gmc_tmz_set(adev);
 
+       if (amdgpu_num_kcq > 8 || amdgpu_num_kcq < 0) {
+               amdgpu_num_kcq = 8;
+               dev_warn(adev->dev, "set kernel compute queue number to 8 due to invalid paramter provided by user\n");
+       }
+
        return 0;
 }
 
 
 int amdgpu_force_asic_type = -1;
 int amdgpu_tmz = 0;
 int amdgpu_reset_method = -1; /* auto */
+int amdgpu_num_kcq = -1;
 
 struct amdgpu_mgpu_info mgpu_info = {
        .mutex = __MUTEX_INITIALIZER(mgpu_info.mutex),
 MODULE_PARM_DESC(bad_page_threshold, "Bad page threshold(-1 = auto(default value), 0 = disable bad page retirement)");
 module_param_named(bad_page_threshold, amdgpu_bad_page_threshold, int, 0444);
 
+MODULE_PARM_DESC(num_kcq, "number of kernel compute queue user want to setup (8 if set to greater than 8 or less than 0, only affect gfx 8+)");
+module_param_named(num_kcq, amdgpu_num_kcq, int, 0444);
+
 static const struct pci_device_id pciidlist[] = {
 #ifdef  CONFIG_DRM_AMDGPU_SI
        {0x1002, 0x6780, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TAHITI},
 
 
 void amdgpu_gfx_compute_queue_acquire(struct amdgpu_device *adev)
 {
-       int i, queue, pipe, mec;
+       int i, queue, pipe;
        bool multipipe_policy = amdgpu_gfx_is_multipipe_capable(adev);
-
-       /* policy for amdgpu compute queue ownership */
-       for (i = 0; i < AMDGPU_MAX_COMPUTE_QUEUES; ++i) {
-               queue = i % adev->gfx.mec.num_queue_per_pipe;
-               pipe = (i / adev->gfx.mec.num_queue_per_pipe)
-                       % adev->gfx.mec.num_pipe_per_mec;
-               mec = (i / adev->gfx.mec.num_queue_per_pipe)
-                       / adev->gfx.mec.num_pipe_per_mec;
-
-               /* we've run out of HW */
-               if (mec >= adev->gfx.mec.num_mec)
-                       break;
-
-               if (multipipe_policy) {
-                       /* policy: amdgpu owns the first two queues of the first MEC */
-                       if (mec == 0 && queue < 2)
-                               set_bit(i, adev->gfx.mec.queue_bitmap);
-               } else {
-                       /* policy: amdgpu owns all queues in the first pipe */
-                       if (mec == 0 && pipe == 0)
-                               set_bit(i, adev->gfx.mec.queue_bitmap);
+       int max_queues_per_mec = min(adev->gfx.mec.num_pipe_per_mec *
+                                    adev->gfx.mec.num_queue_per_pipe,
+                                    adev->gfx.num_compute_rings);
+
+       if (multipipe_policy) {
+               /* policy: make queues evenly cross all pipes on MEC1 only */
+               for (i = 0; i < max_queues_per_mec; i++) {
+                       pipe = i % adev->gfx.mec.num_pipe_per_mec;
+                       queue = (i / adev->gfx.mec.num_pipe_per_mec) %
+                               adev->gfx.mec.num_queue_per_pipe;
+
+                       set_bit(pipe * adev->gfx.mec.num_queue_per_pipe + queue,
+                                       adev->gfx.mec.queue_bitmap);
                }
+       } else {
+               /* policy: amdgpu owns all queues in the given pipe */
+               for (i = 0; i < max_queues_per_mec; ++i)
+                       set_bit(i, adev->gfx.mec.queue_bitmap);
        }
 
-       /* update the number of active compute rings */
-       adev->gfx.num_compute_rings =
-               bitmap_weight(adev->gfx.mec.queue_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
-
-       /* If you hit this case and edited the policy, you probably just
-        * need to increase AMDGPU_MAX_COMPUTE_RINGS */
-       if (WARN_ON(adev->gfx.num_compute_rings > AMDGPU_MAX_COMPUTE_RINGS))
-               adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
+       dev_dbg(adev->dev, "mec queue bitmap weight=%d\n", bitmap_weight(adev->gfx.mec.queue_bitmap, AMDGPU_MAX_COMPUTE_QUEUES));
 }
 
 void amdgpu_gfx_graphics_queue_acquire(struct amdgpu_device *adev)
 
        amdgpu_gfx_compute_queue_acquire(adev);
        mec_hpd_size = adev->gfx.num_compute_rings * GFX10_MEC_HPD_SIZE;
 
-       r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
-                                     AMDGPU_GEM_DOMAIN_GTT,
-                                     &adev->gfx.mec.hpd_eop_obj,
-                                     &adev->gfx.mec.hpd_eop_gpu_addr,
-                                     (void **)&hpd);
-       if (r) {
-               dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
-               gfx_v10_0_mec_fini(adev);
-               return r;
-       }
+       if (mec_hpd_size) {
+               r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+                                             AMDGPU_GEM_DOMAIN_GTT,
+                                             &adev->gfx.mec.hpd_eop_obj,
+                                             &adev->gfx.mec.hpd_eop_gpu_addr,
+                                             (void **)&hpd);
+               if (r) {
+                       dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
+                       gfx_v10_0_mec_fini(adev);
+                       return r;
+               }
 
-       memset(hpd, 0, mec_hpd_size);
+               memset(hpd, 0, mec_hpd_size);
 
-       amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
-       amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+       }
 
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
                mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
                break;
        }
 
-       adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
+       adev->gfx.num_compute_rings = amdgpu_num_kcq;
 
        gfx_v10_0_set_kiq_pm4_funcs(adev);
        gfx_v10_0_set_ring_funcs(adev);
 
        amdgpu_gfx_compute_queue_acquire(adev);
 
        mec_hpd_size = adev->gfx.num_compute_rings * GFX8_MEC_HPD_SIZE;
+       if (mec_hpd_size) {
+               r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+                                             AMDGPU_GEM_DOMAIN_VRAM,
+                                             &adev->gfx.mec.hpd_eop_obj,
+                                             &adev->gfx.mec.hpd_eop_gpu_addr,
+                                             (void **)&hpd);
+               if (r) {
+                       dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
+                       return r;
+               }
 
-       r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
-                                     AMDGPU_GEM_DOMAIN_VRAM,
-                                     &adev->gfx.mec.hpd_eop_obj,
-                                     &adev->gfx.mec.hpd_eop_gpu_addr,
-                                     (void **)&hpd);
-       if (r) {
-               dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
-               return r;
-       }
-
-       memset(hpd, 0, mec_hpd_size);
+               memset(hpd, 0, mec_hpd_size);
 
-       amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
-       amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+       }
 
        return 0;
 }
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        adev->gfx.num_gfx_rings = GFX8_NUM_GFX_RINGS;
-       adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
+       adev->gfx.num_compute_rings = amdgpu_num_kcq;
        adev->gfx.funcs = &gfx_v8_0_gfx_funcs;
        gfx_v8_0_set_ring_funcs(adev);
        gfx_v8_0_set_irq_funcs(adev);
 
        /* take ownership of the relevant compute queues */
        amdgpu_gfx_compute_queue_acquire(adev);
        mec_hpd_size = adev->gfx.num_compute_rings * GFX9_MEC_HPD_SIZE;
+       if (mec_hpd_size) {
+               r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
+                                             AMDGPU_GEM_DOMAIN_VRAM,
+                                             &adev->gfx.mec.hpd_eop_obj,
+                                             &adev->gfx.mec.hpd_eop_gpu_addr,
+                                             (void **)&hpd);
+               if (r) {
+                       dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
+                       gfx_v9_0_mec_fini(adev);
+                       return r;
+               }
 
-       r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
-                                     AMDGPU_GEM_DOMAIN_VRAM,
-                                     &adev->gfx.mec.hpd_eop_obj,
-                                     &adev->gfx.mec.hpd_eop_gpu_addr,
-                                     (void **)&hpd);
-       if (r) {
-               dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
-               gfx_v9_0_mec_fini(adev);
-               return r;
-       }
-
-       memset(hpd, 0, mec_hpd_size);
+               memset(hpd, 0, mec_hpd_size);
 
-       amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
-       amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
+               amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
+       }
 
        mec_hdr = (const struct gfx_firmware_header_v1_0 *)adev->gfx.mec_fw->data;
 
                adev->gfx.num_gfx_rings = 0;
        else
                adev->gfx.num_gfx_rings = GFX9_NUM_GFX_RINGS;
-       adev->gfx.num_compute_rings = AMDGPU_MAX_COMPUTE_RINGS;
+       adev->gfx.num_compute_rings = amdgpu_num_kcq;
        gfx_v9_0_set_kiq_pm4_funcs(adev);
        gfx_v9_0_set_ring_funcs(adev);
        gfx_v9_0_set_irq_funcs(adev);