|
47 | 47 |
|
48 | 48 | #include "amdgpu_ras.h"
|
49 | 49 |
|
| 50 | +#include "amdgpu_ring_mux.h" |
50 | 51 | #include "gfx_v9_4.h"
|
51 | 52 | #include "gfx_v9_0.h"
|
52 | 53 | #include "gfx_v9_4_2.h"
|
|
56 | 57 | #include "asic_reg/gc/gc_9_0_default.h"
|
57 | 58 |
|
58 | 59 | #define GFX9_NUM_GFX_RINGS 1
|
| 60 | +#define GFX9_NUM_SW_GFX_RINGS 2 |
59 | 61 | #define GFX9_MEC_HPD_SIZE 4096
|
60 | 62 | #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
|
61 | 63 | #define RLC_SAVE_RESTORE_ADDR_STARTING_OFFSET 0x00000000L
|
@@ -2103,6 +2105,7 @@ static int gfx_v9_0_sw_init(void *handle)
|
2103 | 2105 | struct amdgpu_ring *ring;
|
2104 | 2106 | struct amdgpu_kiq *kiq;
|
2105 | 2107 | struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
| 2108 | + unsigned int hw_prio; |
2106 | 2109 |
|
2107 | 2110 | switch (adev->ip_versions[GC_HWIP][0]) {
|
2108 | 2111 | case IP_VERSION(9, 0, 1):
|
@@ -2186,13 +2189,51 @@ static int gfx_v9_0_sw_init(void *handle)
|
2186 | 2189 | sprintf(ring->name, "gfx_%d", i);
|
2187 | 2190 | ring->use_doorbell = true;
|
2188 | 2191 | ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
|
| 2192 | + |
| 2193 | + /* disable scheduler on the real ring */ |
| 2194 | + ring->no_scheduler = true; |
2189 | 2195 | r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq,
|
2190 | 2196 | AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP,
|
2191 | 2197 | AMDGPU_RING_PRIO_DEFAULT, NULL);
|
2192 | 2198 | if (r)
|
2193 | 2199 | return r;
|
2194 | 2200 | }
|
2195 | 2201 |
|
| 2202 | + /* set up the software rings */ |
| 2203 | + if (adev->gfx.num_gfx_rings) { |
| 2204 | + for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) { |
| 2205 | + ring = &adev->gfx.sw_gfx_ring[i]; |
| 2206 | + ring->ring_obj = NULL; |
| 2207 | + sprintf(ring->name, amdgpu_sw_ring_name(i)); |
| 2208 | + ring->use_doorbell = true; |
| 2209 | + ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1; |
| 2210 | + ring->is_sw_ring = true; |
| 2211 | + hw_prio = amdgpu_sw_ring_priority(i); |
| 2212 | + r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq, |
| 2213 | + AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP, hw_prio, |
| 2214 | + NULL); |
| 2215 | + if (r) |
| 2216 | + return r; |
| 2217 | + ring->wptr = 0; |
| 2218 | + } |
| 2219 | + |
| 2220 | + /* init the muxer and add software rings */ |
| 2221 | + r = amdgpu_ring_mux_init(&adev->gfx.muxer, &adev->gfx.gfx_ring[0], |
| 2222 | + GFX9_NUM_SW_GFX_RINGS); |
| 2223 | + if (r) { |
| 2224 | + DRM_ERROR("amdgpu_ring_mux_init failed(%d)\n", r); |
| 2225 | + return r; |
| 2226 | + } |
| 2227 | + for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) { |
| 2228 | + r = amdgpu_ring_mux_add_sw_ring(&adev->gfx.muxer, |
| 2229 | + &adev->gfx.sw_gfx_ring[i]); |
| 2230 | + if (r) { |
| 2231 | + DRM_ERROR("amdgpu_ring_mux_add_sw_ring failed(%d)\n", r); |
| 2232 | + return r; |
| 2233 | + } |
| 2234 | + } |
| 2235 | + } |
| 2236 | + |
2196 | 2237 | /* set up the compute queues - allocate horizontally across pipes */
|
2197 | 2238 | ring_id = 0;
|
2198 | 2239 | for (i = 0; i < adev->gfx.mec.num_mec; ++i) {
|
@@ -2243,6 +2284,12 @@ static int gfx_v9_0_sw_fini(void *handle)
|
2243 | 2284 | int i;
|
2244 | 2285 | struct amdgpu_device *adev = (struct amdgpu_device *)handle;
|
2245 | 2286 |
|
| 2287 | + if (adev->gfx.num_gfx_rings) { |
| 2288 | + for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) |
| 2289 | + amdgpu_ring_fini(&adev->gfx.sw_gfx_ring[i]); |
| 2290 | + amdgpu_ring_mux_fini(&adev->gfx.muxer); |
| 2291 | + } |
| 2292 | + |
2246 | 2293 | for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
2247 | 2294 | amdgpu_ring_fini(&adev->gfx.gfx_ring[i]);
|
2248 | 2295 | for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
@@ -5712,7 +5759,11 @@ static int gfx_v9_0_eop_irq(struct amdgpu_device *adev,
|
5712 | 5759 |
|
5713 | 5760 | switch (me_id) {
|
5714 | 5761 | case 0:
|
5715 |
| - amdgpu_fence_process(&adev->gfx.gfx_ring[0]); |
| 5762 | + /* Fence signals are handled on the software rings*/ |
| 5763 | + if (adev->gfx.num_gfx_rings) { |
| 5764 | + for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) |
| 5765 | + amdgpu_fence_process(&adev->gfx.sw_gfx_ring[i]); |
| 5766 | + } |
5716 | 5767 | break;
|
5717 | 5768 | case 1:
|
5718 | 5769 | case 2:
|
@@ -6717,6 +6768,61 @@ static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_gfx = {
|
6717 | 6768 | .emit_mem_sync = gfx_v9_0_emit_mem_sync,
|
6718 | 6769 | };
|
6719 | 6770 |
|
| 6771 | +static const struct amdgpu_ring_funcs gfx_v9_0_sw_ring_funcs_gfx = { |
| 6772 | + .type = AMDGPU_RING_TYPE_GFX, |
| 6773 | + .align_mask = 0xff, |
| 6774 | + .nop = PACKET3(PACKET3_NOP, 0x3FFF), |
| 6775 | + .support_64bit_ptrs = true, |
| 6776 | + .secure_submission_supported = true, |
| 6777 | + .vmhub = AMDGPU_GFXHUB_0, |
| 6778 | + .get_rptr = amdgpu_sw_ring_get_rptr_gfx, |
| 6779 | + .get_wptr = amdgpu_sw_ring_get_wptr_gfx, |
| 6780 | + .set_wptr = amdgpu_sw_ring_set_wptr_gfx, |
| 6781 | + .emit_frame_size = /* totally 242 maximum if 16 IBs */ |
| 6782 | + 5 + /* COND_EXEC */ |
| 6783 | + 7 + /* PIPELINE_SYNC */ |
| 6784 | + SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 + |
| 6785 | + SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 + |
| 6786 | + 2 + /* VM_FLUSH */ |
| 6787 | + 8 + /* FENCE for VM_FLUSH */ |
| 6788 | + 20 + /* GDS switch */ |
| 6789 | + 4 + /* double SWITCH_BUFFER, |
| 6790 | + * the first COND_EXEC jump to the place just |
| 6791 | + * prior to this double SWITCH_BUFFER |
| 6792 | + */ |
| 6793 | + 5 + /* COND_EXEC */ |
| 6794 | + 7 + /* HDP_flush */ |
| 6795 | + 4 + /* VGT_flush */ |
| 6796 | + 14 + /* CE_META */ |
| 6797 | + 31 + /* DE_META */ |
| 6798 | + 3 + /* CNTX_CTRL */ |
| 6799 | + 5 + /* HDP_INVL */ |
| 6800 | + 8 + 8 + /* FENCE x2 */ |
| 6801 | + 2 + /* SWITCH_BUFFER */ |
| 6802 | + 7, /* gfx_v9_0_emit_mem_sync */ |
| 6803 | + .emit_ib_size = 4, /* gfx_v9_0_ring_emit_ib_gfx */ |
| 6804 | + .emit_ib = gfx_v9_0_ring_emit_ib_gfx, |
| 6805 | + .emit_fence = gfx_v9_0_ring_emit_fence, |
| 6806 | + .emit_pipeline_sync = gfx_v9_0_ring_emit_pipeline_sync, |
| 6807 | + .emit_vm_flush = gfx_v9_0_ring_emit_vm_flush, |
| 6808 | + .emit_gds_switch = gfx_v9_0_ring_emit_gds_switch, |
| 6809 | + .emit_hdp_flush = gfx_v9_0_ring_emit_hdp_flush, |
| 6810 | + .test_ring = gfx_v9_0_ring_test_ring, |
| 6811 | + .test_ib = gfx_v9_0_ring_test_ib, |
| 6812 | + .insert_nop = amdgpu_sw_ring_insert_nop, |
| 6813 | + .pad_ib = amdgpu_ring_generic_pad_ib, |
| 6814 | + .emit_switch_buffer = gfx_v9_ring_emit_sb, |
| 6815 | + .emit_cntxcntl = gfx_v9_ring_emit_cntxcntl, |
| 6816 | + .init_cond_exec = gfx_v9_0_ring_emit_init_cond_exec, |
| 6817 | + .patch_cond_exec = gfx_v9_0_ring_emit_patch_cond_exec, |
| 6818 | + .emit_frame_cntl = gfx_v9_0_ring_emit_frame_cntl, |
| 6819 | + .emit_wreg = gfx_v9_0_ring_emit_wreg, |
| 6820 | + .emit_reg_wait = gfx_v9_0_ring_emit_reg_wait, |
| 6821 | + .emit_reg_write_reg_wait = gfx_v9_0_ring_emit_reg_write_reg_wait, |
| 6822 | + .soft_recovery = gfx_v9_0_ring_soft_recovery, |
| 6823 | + .emit_mem_sync = gfx_v9_0_emit_mem_sync, |
| 6824 | +}; |
| 6825 | + |
6720 | 6826 | static const struct amdgpu_ring_funcs gfx_v9_0_ring_funcs_compute = {
|
6721 | 6827 | .type = AMDGPU_RING_TYPE_COMPUTE,
|
6722 | 6828 | .align_mask = 0xff,
|
@@ -6794,6 +6900,11 @@ static void gfx_v9_0_set_ring_funcs(struct amdgpu_device *adev)
|
6794 | 6900 | for (i = 0; i < adev->gfx.num_gfx_rings; i++)
|
6795 | 6901 | adev->gfx.gfx_ring[i].funcs = &gfx_v9_0_ring_funcs_gfx;
|
6796 | 6902 |
|
| 6903 | + if (adev->gfx.num_gfx_rings) { |
| 6904 | + for (i = 0; i < GFX9_NUM_SW_GFX_RINGS; i++) |
| 6905 | + adev->gfx.sw_gfx_ring[i].funcs = &gfx_v9_0_sw_ring_funcs_gfx; |
| 6906 | + } |
| 6907 | + |
6797 | 6908 | for (i = 0; i < adev->gfx.num_compute_rings; i++)
|
6798 | 6909 | adev->gfx.compute_ring[i].funcs = &gfx_v9_0_ring_funcs_compute;
|
6799 | 6910 | }
|
|
0 commit comments