diff options
author | Andres Rodriguez <andresx7@gmail.com> | 2017-02-01 19:08:23 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-05-31 16:48:52 -0400 |
commit | 42794b27cc628d44db28f62f3333bd12416b597f (patch) | |
tree | 893f1c3b7572c1baadcaacb61dce15d8881efe2b | |
parent | d59095f7dd8810e67bdad7a65131903646ebc444 (diff) |
drm/amdgpu: take ownership of per-pipe configuration v3
Make amdgpu the owner of all per-pipe state of the HQDs.
This change will allow us to split the queues between kfd and amdgpu
with a queue granularity instead of pipe granularity.
This patch fixes kfd allocating an HDP_EOP region for its 3 pipes which
goes unused.
v2: support for gfx9
v3: fix gfx7 HPD intitialization
Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Andres Rodriguez <andresx7@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 36 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 45 |
7 files changed, 70 insertions, 86 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index abf5a58edc82..8b269f17506c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -902,9 +902,9 @@ struct amdgpu_mec { | |||
902 | u64 hpd_eop_gpu_addr; | 902 | u64 hpd_eop_gpu_addr; |
903 | struct amdgpu_bo *mec_fw_obj; | 903 | struct amdgpu_bo *mec_fw_obj; |
904 | u64 mec_fw_gpu_addr; | 904 | u64 mec_fw_gpu_addr; |
905 | u32 num_pipe; | ||
906 | u32 num_mec; | 905 | u32 num_mec; |
907 | u32 num_queue; | 906 | u32 num_pipe_per_mec; |
907 | u32 num_queue_per_pipe; | ||
908 | void *mqd_backup[AMDGPU_MAX_COMPUTE_RINGS + 1]; | 908 | void *mqd_backup[AMDGPU_MAX_COMPUTE_RINGS + 1]; |
909 | }; | 909 | }; |
910 | 910 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index 038b7ea375b0..910f9d32e049 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | |||
@@ -244,18 +244,7 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, | |||
244 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, | 244 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, |
245 | uint32_t hpd_size, uint64_t hpd_gpu_addr) | 245 | uint32_t hpd_size, uint64_t hpd_gpu_addr) |
246 | { | 246 | { |
247 | struct amdgpu_device *adev = get_amdgpu_device(kgd); | 247 | /* amdgpu owns the per-pipe state */ |
248 | |||
249 | uint32_t mec = (++pipe_id / CIK_PIPE_PER_MEC) + 1; | ||
250 | uint32_t pipe = (pipe_id % CIK_PIPE_PER_MEC); | ||
251 | |||
252 | lock_srbm(kgd, mec, pipe, 0, 0); | ||
253 | WREG32(mmCP_HPD_EOP_BASE_ADDR, lower_32_bits(hpd_gpu_addr >> 8)); | ||
254 | WREG32(mmCP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(hpd_gpu_addr >> 8)); | ||
255 | WREG32(mmCP_HPD_EOP_VMID, 0); | ||
256 | WREG32(mmCP_HPD_EOP_CONTROL, hpd_size); | ||
257 | unlock_srbm(kgd); | ||
258 | |||
259 | return 0; | 248 | return 0; |
260 | } | 249 | } |
261 | 250 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index 8af29756a9d9..6ba94e96ae80 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | |||
@@ -206,6 +206,7 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, | |||
206 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, | 206 | static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, |
207 | uint32_t hpd_size, uint64_t hpd_gpu_addr) | 207 | uint32_t hpd_size, uint64_t hpd_gpu_addr) |
208 | { | 208 | { |
209 | /* amdgpu owns the per-pipe state */ | ||
209 | return 0; | 210 | return 0; |
210 | } | 211 | } |
211 | 212 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c index b12a60924e71..8258e3359c17 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | |||
@@ -2827,6 +2827,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev) | |||
2827 | { | 2827 | { |
2828 | int r; | 2828 | int r; |
2829 | u32 *hpd; | 2829 | u32 *hpd; |
2830 | size_t mec_hpd_size; | ||
2830 | 2831 | ||
2831 | /* | 2832 | /* |
2832 | * KV: 2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total | 2833 | * KV: 2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total |
@@ -2834,13 +2835,26 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev) | |||
2834 | * Nonetheless, we assign only 1 pipe because all other pipes will | 2835 | * Nonetheless, we assign only 1 pipe because all other pipes will |
2835 | * be handled by KFD | 2836 | * be handled by KFD |
2836 | */ | 2837 | */ |
2837 | adev->gfx.mec.num_mec = 1; | 2838 | switch (adev->asic_type) { |
2838 | adev->gfx.mec.num_pipe = 1; | 2839 | case CHIP_KAVERI: |
2839 | adev->gfx.mec.num_queue = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * 8; | 2840 | adev->gfx.mec.num_mec = 2; |
2841 | break; | ||
2842 | case CHIP_BONAIRE: | ||
2843 | case CHIP_HAWAII: | ||
2844 | case CHIP_KABINI: | ||
2845 | case CHIP_MULLINS: | ||
2846 | default: | ||
2847 | adev->gfx.mec.num_mec = 1; | ||
2848 | break; | ||
2849 | } | ||
2850 | adev->gfx.mec.num_pipe_per_mec = 4; | ||
2851 | adev->gfx.mec.num_queue_per_pipe = 8; | ||
2840 | 2852 | ||
2853 | mec_hpd_size = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe_per_mec | ||
2854 | * GFX7_MEC_HPD_SIZE * 2; | ||
2841 | if (adev->gfx.mec.hpd_eop_obj == NULL) { | 2855 | if (adev->gfx.mec.hpd_eop_obj == NULL) { |
2842 | r = amdgpu_bo_create(adev, | 2856 | r = amdgpu_bo_create(adev, |
2843 | adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * GFX7_MEC_HPD_SIZE * 2, | 2857 | mec_hpd_size, |
2844 | PAGE_SIZE, true, | 2858 | PAGE_SIZE, true, |
2845 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, | 2859 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, |
2846 | &adev->gfx.mec.hpd_eop_obj); | 2860 | &adev->gfx.mec.hpd_eop_obj); |
@@ -2870,7 +2884,7 @@ static int gfx_v7_0_mec_init(struct amdgpu_device *adev) | |||
2870 | } | 2884 | } |
2871 | 2885 | ||
2872 | /* clear memory. Not sure if this is required or not */ | 2886 | /* clear memory. Not sure if this is required or not */ |
2873 | memset(hpd, 0, adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * GFX7_MEC_HPD_SIZE * 2); | 2887 | memset(hpd, 0, mec_hpd_size); |
2874 | 2888 | ||
2875 | amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj); | 2889 | amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj); |
2876 | amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj); | 2890 | amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj); |
@@ -2917,16 +2931,18 @@ struct hqd_registers | |||
2917 | u32 cp_mqd_control; | 2931 | u32 cp_mqd_control; |
2918 | }; | 2932 | }; |
2919 | 2933 | ||
2920 | static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev, int me, int pipe) | 2934 | static void gfx_v7_0_compute_pipe_init(struct amdgpu_device *adev, |
2935 | int mec, int pipe) | ||
2921 | { | 2936 | { |
2922 | u64 eop_gpu_addr; | 2937 | u64 eop_gpu_addr; |
2923 | u32 tmp; | 2938 | u32 tmp; |
2924 | size_t eop_offset = me * pipe * GFX7_MEC_HPD_SIZE * 2; | 2939 | size_t eop_offset = (mec * adev->gfx.mec.num_pipe_per_mec + pipe) |
2940 | * GFX7_MEC_HPD_SIZE * 2; | ||
2925 | 2941 | ||
2926 | mutex_lock(&adev->srbm_mutex); | 2942 | mutex_lock(&adev->srbm_mutex); |
2927 | eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + eop_offset; | 2943 | eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr + eop_offset; |
2928 | 2944 | ||
2929 | cik_srbm_select(adev, me, pipe, 0, 0); | 2945 | cik_srbm_select(adev, mec + 1, pipe, 0, 0); |
2930 | 2946 | ||
2931 | /* write the EOP addr */ | 2947 | /* write the EOP addr */ |
2932 | WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); | 2948 | WREG32(mmCP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); |
@@ -3208,9 +3224,9 @@ static int gfx_v7_0_cp_compute_resume(struct amdgpu_device *adev) | |||
3208 | tmp |= (1 << 23); | 3224 | tmp |= (1 << 23); |
3209 | WREG32(mmCP_CPF_DEBUG, tmp); | 3225 | WREG32(mmCP_CPF_DEBUG, tmp); |
3210 | 3226 | ||
3211 | /* init the pipes */ | 3227 | /* init all pipes (even the ones we don't own) */ |
3212 | for (i = 0; i < adev->gfx.mec.num_mec; i++) | 3228 | for (i = 0; i < adev->gfx.mec.num_mec; i++) |
3213 | for (j = 0; j < adev->gfx.mec.num_pipe; j++) | 3229 | for (j = 0; j < adev->gfx.mec.num_pipe_per_mec; j++) |
3214 | gfx_v7_0_compute_pipe_init(adev, i, j); | 3230 | gfx_v7_0_compute_pipe_init(adev, i, j); |
3215 | 3231 | ||
3216 | /* init the queues */ | 3232 | /* init the queues */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 467a0e3ff5a5..8c2241631ade 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | |||
@@ -1426,18 +1426,33 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev) | |||
1426 | { | 1426 | { |
1427 | int r; | 1427 | int r; |
1428 | u32 *hpd; | 1428 | u32 *hpd; |
1429 | size_t mec_hpd_size; | ||
1429 | 1430 | ||
1430 | /* | 1431 | switch (adev->asic_type) { |
1431 | * we assign only 1 pipe because all other pipes will | 1432 | case CHIP_FIJI: |
1432 | * be handled by KFD | 1433 | case CHIP_TONGA: |
1433 | */ | 1434 | case CHIP_POLARIS11: |
1434 | adev->gfx.mec.num_mec = 1; | 1435 | case CHIP_POLARIS12: |
1435 | adev->gfx.mec.num_pipe = 1; | 1436 | case CHIP_POLARIS10: |
1436 | adev->gfx.mec.num_queue = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * 8; | 1437 | case CHIP_CARRIZO: |
1438 | adev->gfx.mec.num_mec = 2; | ||
1439 | break; | ||
1440 | case CHIP_TOPAZ: | ||
1441 | case CHIP_STONEY: | ||
1442 | default: | ||
1443 | adev->gfx.mec.num_mec = 1; | ||
1444 | break; | ||
1445 | } | ||
1446 | |||
1447 | adev->gfx.mec.num_pipe_per_mec = 4; | ||
1448 | adev->gfx.mec.num_queue_per_pipe = 8; | ||
1449 | |||
1450 | /* only 1 pipe of the first MEC is owned by amdgpu */ | ||
1451 | mec_hpd_size = 1 * 1 * adev->gfx.mec.num_queue_per_pipe * GFX8_MEC_HPD_SIZE; | ||
1437 | 1452 | ||
1438 | if (adev->gfx.mec.hpd_eop_obj == NULL) { | 1453 | if (adev->gfx.mec.hpd_eop_obj == NULL) { |
1439 | r = amdgpu_bo_create(adev, | 1454 | r = amdgpu_bo_create(adev, |
1440 | adev->gfx.mec.num_queue * GFX8_MEC_HPD_SIZE, | 1455 | mec_hpd_size, |
1441 | PAGE_SIZE, true, | 1456 | PAGE_SIZE, true, |
1442 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, | 1457 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, |
1443 | &adev->gfx.mec.hpd_eop_obj); | 1458 | &adev->gfx.mec.hpd_eop_obj); |
@@ -1466,7 +1481,7 @@ static int gfx_v8_0_mec_init(struct amdgpu_device *adev) | |||
1466 | return r; | 1481 | return r; |
1467 | } | 1482 | } |
1468 | 1483 | ||
1469 | memset(hpd, 0, adev->gfx.mec.num_queue * GFX8_MEC_HPD_SIZE); | 1484 | memset(hpd, 0, mec_hpd_size); |
1470 | 1485 | ||
1471 | amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj); | 1486 | amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj); |
1472 | amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj); | 1487 | amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c index 9a0029d80ff4..9f432e45b31b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | |||
@@ -865,20 +865,28 @@ static int gfx_v9_0_mec_init(struct amdgpu_device *adev) | |||
865 | const __le32 *fw_data; | 865 | const __le32 *fw_data; |
866 | unsigned fw_size; | 866 | unsigned fw_size; |
867 | u32 *fw; | 867 | u32 *fw; |
868 | size_t mec_hpd_size; | ||
868 | 869 | ||
869 | const struct gfx_firmware_header_v1_0 *mec_hdr; | 870 | const struct gfx_firmware_header_v1_0 *mec_hdr; |
870 | 871 | ||
871 | /* | 872 | switch (adev->asic_type) { |
872 | * we assign only 1 pipe because all other pipes will | 873 | case CHIP_VEGA10: |
873 | * be handled by KFD | 874 | adev->gfx.mec.num_mec = 2; |
874 | */ | 875 | break; |
875 | adev->gfx.mec.num_mec = 1; | 876 | default: |
876 | adev->gfx.mec.num_pipe = 1; | 877 | adev->gfx.mec.num_mec = 1; |
877 | adev->gfx.mec.num_queue = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe * 8; | 878 | break; |
879 | } | ||
880 | |||
881 | adev->gfx.mec.num_pipe_per_mec = 4; | ||
882 | adev->gfx.mec.num_queue_per_pipe = 8; | ||
883 | |||
884 | /* only 1 pipe of the first MEC is owned by amdgpu */ | ||
885 | mec_hpd_size = 1 * 1 * adev->gfx.mec.num_queue_per_pipe * GFX9_MEC_HPD_SIZE; | ||
878 | 886 | ||
879 | if (adev->gfx.mec.hpd_eop_obj == NULL) { | 887 | if (adev->gfx.mec.hpd_eop_obj == NULL) { |
880 | r = amdgpu_bo_create(adev, | 888 | r = amdgpu_bo_create(adev, |
881 | adev->gfx.mec.num_queue * GFX9_MEC_HPD_SIZE, | 889 | mec_hpd_size, |
882 | PAGE_SIZE, true, | 890 | PAGE_SIZE, true, |
883 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, | 891 | AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL, |
884 | &adev->gfx.mec.hpd_eop_obj); | 892 | &adev->gfx.mec.hpd_eop_obj); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index f49c551195b3..c064dea3f285 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -472,55 +472,10 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, | |||
472 | int init_pipelines(struct device_queue_manager *dqm, | 472 | int init_pipelines(struct device_queue_manager *dqm, |
473 | unsigned int pipes_num, unsigned int first_pipe) | 473 | unsigned int pipes_num, unsigned int first_pipe) |
474 | { | 474 | { |
475 | void *hpdptr; | ||
476 | struct mqd_manager *mqd; | ||
477 | unsigned int i, err, inx; | ||
478 | uint64_t pipe_hpd_addr; | ||
479 | |||
480 | BUG_ON(!dqm || !dqm->dev); | 475 | BUG_ON(!dqm || !dqm->dev); |
481 | 476 | ||
482 | pr_debug("kfd: In func %s\n", __func__); | 477 | pr_debug("kfd: In func %s\n", __func__); |
483 | 478 | ||
484 | /* | ||
485 | * Allocate memory for the HPDs. This is hardware-owned per-pipe data. | ||
486 | * The driver never accesses this memory after zeroing it. | ||
487 | * It doesn't even have to be saved/restored on suspend/resume | ||
488 | * because it contains no data when there are no active queues. | ||
489 | */ | ||
490 | |||
491 | err = kfd_gtt_sa_allocate(dqm->dev, CIK_HPD_EOP_BYTES * pipes_num, | ||
492 | &dqm->pipeline_mem); | ||
493 | |||
494 | if (err) { | ||
495 | pr_err("kfd: error allocate vidmem num pipes: %d\n", | ||
496 | pipes_num); | ||
497 | return -ENOMEM; | ||
498 | } | ||
499 | |||
500 | hpdptr = dqm->pipeline_mem->cpu_ptr; | ||
501 | dqm->pipelines_addr = dqm->pipeline_mem->gpu_addr; | ||
502 | |||
503 | memset(hpdptr, 0, CIK_HPD_EOP_BYTES * pipes_num); | ||
504 | |||
505 | mqd = dqm->ops.get_mqd_manager(dqm, KFD_MQD_TYPE_COMPUTE); | ||
506 | if (mqd == NULL) { | ||
507 | kfd_gtt_sa_free(dqm->dev, dqm->pipeline_mem); | ||
508 | return -ENOMEM; | ||
509 | } | ||
510 | |||
511 | for (i = 0; i < pipes_num; i++) { | ||
512 | inx = i + first_pipe; | ||
513 | /* | ||
514 | * HPD buffer on GTT is allocated by amdkfd, no need to waste | ||
515 | * space in GTT for pipelines we don't initialize | ||
516 | */ | ||
517 | pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES; | ||
518 | pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr); | ||
519 | /* = log2(bytes/4)-1 */ | ||
520 | dqm->dev->kfd2kgd->init_pipeline(dqm->dev->kgd, inx, | ||
521 | CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr); | ||
522 | } | ||
523 | |||
524 | return 0; | 479 | return 0; |
525 | } | 480 | } |
526 | 481 | ||