diff options
author | Ben Goz <ben.goz@amd.com> | 2015-01-12 07:28:46 -0500 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@amd.com> | 2015-01-12 07:28:46 -0500 |
commit | a22fc85495575d81c36db24b12f66fd314b7ced1 (patch) | |
tree | d9386ece4b610901a6b8239f818071f016c620ae /drivers/gpu/drm/amd | |
parent | 45c9a5e4297b9a07d94ff8195ff6f21ba3581ad6 (diff) |
drm/amdkfd: Add initial VI support for DQM
This patch starts to add support for the VI APU in the DQM module.
Because most (more than 90%) of the DQM code is shared among AMD's APUs, we
chose a design that performs most/all the code in the shared DQM file
(kfd_device_queue_manager.c). If there is H/W specific code to be executed,
than it is written in an asic-specific extension function for that H/W.
That asic-specific extension function is called from the shared function at the
appropriate time. This requires that for every asic-specific extension function
that is implemented in a specific ASIC, there will be an equivalent
implementation in ALL ASICs, even if those implementations are just stubs.
That way we achieve:
- Maintainability: by having one copy of most of the code, we only need to
fix bugs at one locations
- Readability: very clear what is the shared code and what is done per ASIC
- Extensibility: very easy to add new H/W specific files/functions
Signed-off-by: Ben Goz <ben.goz@amd.com>
Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 113 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c | 135 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c | 64 |
5 files changed, 238 insertions, 86 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/Makefile b/drivers/gpu/drm/amd/amdkfd/Makefile index bc6053f8b843..7558683c6935 100644 --- a/drivers/gpu/drm/amd/amdkfd/Makefile +++ b/drivers/gpu/drm/amd/amdkfd/Makefile | |||
@@ -10,6 +10,7 @@ amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \ | |||
10 | kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \ | 10 | kfd_mqd_manager_cik.o kfd_mqd_manager_vi.o \ |
11 | kfd_kernel_queue.o kfd_packet_manager.o \ | 11 | kfd_kernel_queue.o kfd_packet_manager.o \ |
12 | kfd_process_queue_manager.o kfd_device_queue_manager.o \ | 12 | kfd_process_queue_manager.o kfd_device_queue_manager.o \ |
13 | kfd_device_queue_manager_cik.o kfd_device_queue_manager_vi.o \ | ||
13 | kfd_interrupt.o | 14 | kfd_interrupt.o |
14 | 15 | ||
15 | obj-$(CONFIG_HSA_AMD) += amdkfd.o | 16 | obj-$(CONFIG_HSA_AMD) += amdkfd.o |
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 12c84488551e..b2016245073e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -61,7 +61,7 @@ enum KFD_MQD_TYPE get_mqd_type_from_queue_type(enum kfd_queue_type type) | |||
61 | return KFD_MQD_TYPE_CP; | 61 | return KFD_MQD_TYPE_CP; |
62 | } | 62 | } |
63 | 63 | ||
64 | static inline unsigned int get_pipes_num(struct device_queue_manager *dqm) | 64 | inline unsigned int get_pipes_num(struct device_queue_manager *dqm) |
65 | { | 65 | { |
66 | BUG_ON(!dqm || !dqm->dev); | 66 | BUG_ON(!dqm || !dqm->dev); |
67 | return dqm->dev->shared_resources.compute_pipe_count; | 67 | return dqm->dev->shared_resources.compute_pipe_count; |
@@ -78,7 +78,7 @@ static inline unsigned int get_pipes_num_cpsch(void) | |||
78 | return PIPE_PER_ME_CP_SCHEDULING; | 78 | return PIPE_PER_ME_CP_SCHEDULING; |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline unsigned int | 81 | inline unsigned int |
82 | get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) | 82 | get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) |
83 | { | 83 | { |
84 | uint32_t nybble; | 84 | uint32_t nybble; |
@@ -88,7 +88,7 @@ get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) | |||
88 | return nybble; | 88 | return nybble; |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) | 91 | inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) |
92 | { | 92 | { |
93 | unsigned int shared_base; | 93 | unsigned int shared_base; |
94 | 94 | ||
@@ -97,41 +97,7 @@ static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) | |||
97 | return shared_base; | 97 | return shared_base; |
98 | } | 98 | } |
99 | 99 | ||
100 | static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble); | 100 | void program_sh_mem_settings(struct device_queue_manager *dqm, |
101 | static void init_process_memory(struct device_queue_manager *dqm, | ||
102 | struct qcm_process_device *qpd) | ||
103 | { | ||
104 | struct kfd_process_device *pdd; | ||
105 | unsigned int temp; | ||
106 | |||
107 | BUG_ON(!dqm || !qpd); | ||
108 | |||
109 | pdd = qpd_to_pdd(qpd); | ||
110 | |||
111 | /* check if sh_mem_config register already configured */ | ||
112 | if (qpd->sh_mem_config == 0) { | ||
113 | qpd->sh_mem_config = | ||
114 | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | | ||
115 | DEFAULT_MTYPE(MTYPE_NONCACHED) | | ||
116 | APE1_MTYPE(MTYPE_NONCACHED); | ||
117 | qpd->sh_mem_ape1_limit = 0; | ||
118 | qpd->sh_mem_ape1_base = 0; | ||
119 | } | ||
120 | |||
121 | if (qpd->pqm->process->is_32bit_user_mode) { | ||
122 | temp = get_sh_mem_bases_32(pdd); | ||
123 | qpd->sh_mem_bases = SHARED_BASE(temp); | ||
124 | qpd->sh_mem_config |= PTR32; | ||
125 | } else { | ||
126 | temp = get_sh_mem_bases_nybble_64(pdd); | ||
127 | qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); | ||
128 | } | ||
129 | |||
130 | pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n", | ||
131 | qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases); | ||
132 | } | ||
133 | |||
134 | static void program_sh_mem_settings(struct device_queue_manager *dqm, | ||
135 | struct qcm_process_device *qpd) | 101 | struct qcm_process_device *qpd) |
136 | { | 102 | { |
137 | return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid, | 103 | return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid, |
@@ -391,6 +357,7 @@ static int register_process_nocpsch(struct device_queue_manager *dqm, | |||
391 | struct qcm_process_device *qpd) | 357 | struct qcm_process_device *qpd) |
392 | { | 358 | { |
393 | struct device_process_node *n; | 359 | struct device_process_node *n; |
360 | int retval; | ||
394 | 361 | ||
395 | BUG_ON(!dqm || !qpd); | 362 | BUG_ON(!dqm || !qpd); |
396 | 363 | ||
@@ -405,12 +372,13 @@ static int register_process_nocpsch(struct device_queue_manager *dqm, | |||
405 | mutex_lock(&dqm->lock); | 372 | mutex_lock(&dqm->lock); |
406 | list_add(&n->list, &dqm->queues); | 373 | list_add(&n->list, &dqm->queues); |
407 | 374 | ||
408 | init_process_memory(dqm, qpd); | 375 | retval = dqm->ops_asic_specific.register_process(dqm, qpd); |
376 | |||
409 | dqm->processes_count++; | 377 | dqm->processes_count++; |
410 | 378 | ||
411 | mutex_unlock(&dqm->lock); | 379 | mutex_unlock(&dqm->lock); |
412 | 380 | ||
413 | return 0; | 381 | return retval; |
414 | } | 382 | } |
415 | 383 | ||
416 | static int unregister_process_nocpsch(struct device_queue_manager *dqm, | 384 | static int unregister_process_nocpsch(struct device_queue_manager *dqm, |
@@ -455,34 +423,7 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid, | |||
455 | vmid); | 423 | vmid); |
456 | } | 424 | } |
457 | 425 | ||
458 | static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) | 426 | int init_pipelines(struct device_queue_manager *dqm, |
459 | { | ||
460 | /* In 64-bit mode, we can only control the top 3 bits of the LDS, | ||
461 | * scratch and GPUVM apertures. | ||
462 | * The hardware fills in the remaining 59 bits according to the | ||
463 | * following pattern: | ||
464 | * LDS: X0000000'00000000 - X0000001'00000000 (4GB) | ||
465 | * Scratch: X0000001'00000000 - X0000002'00000000 (4GB) | ||
466 | * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB) | ||
467 | * | ||
468 | * (where X/Y is the configurable nybble with the low-bit 0) | ||
469 | * | ||
470 | * LDS and scratch will have the same top nybble programmed in the | ||
471 | * top 3 bits of SH_MEM_BASES.PRIVATE_BASE. | ||
472 | * GPUVM can have a different top nybble programmed in the | ||
473 | * top 3 bits of SH_MEM_BASES.SHARED_BASE. | ||
474 | * We don't bother to support different top nybbles | ||
475 | * for LDS/Scratch and GPUVM. | ||
476 | */ | ||
477 | |||
478 | BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE || | ||
479 | top_address_nybble == 0); | ||
480 | |||
481 | return PRIVATE_BASE(top_address_nybble << 12) | | ||
482 | SHARED_BASE(top_address_nybble << 12); | ||
483 | } | ||
484 | |||
485 | static int init_pipelines(struct device_queue_manager *dqm, | ||
486 | unsigned int pipes_num, unsigned int first_pipe) | 427 | unsigned int pipes_num, unsigned int first_pipe) |
487 | { | 428 | { |
488 | void *hpdptr; | 429 | void *hpdptr; |
@@ -715,7 +656,7 @@ static int initialize_cpsch(struct device_queue_manager *dqm) | |||
715 | dqm->queue_count = dqm->processes_count = 0; | 656 | dqm->queue_count = dqm->processes_count = 0; |
716 | dqm->sdma_queue_count = 0; | 657 | dqm->sdma_queue_count = 0; |
717 | dqm->active_runlist = false; | 658 | dqm->active_runlist = false; |
718 | retval = init_pipelines(dqm, get_pipes_num(dqm), 0); | 659 | retval = dqm->ops_asic_specific.initialize(dqm); |
719 | if (retval != 0) | 660 | if (retval != 0) |
720 | goto fail_init_pipelines; | 661 | goto fail_init_pipelines; |
721 | 662 | ||
@@ -1035,8 +976,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, | |||
1035 | void __user *alternate_aperture_base, | 976 | void __user *alternate_aperture_base, |
1036 | uint64_t alternate_aperture_size) | 977 | uint64_t alternate_aperture_size) |
1037 | { | 978 | { |
1038 | uint32_t default_mtype; | 979 | bool retval; |
1039 | uint32_t ape1_mtype; | ||
1040 | 980 | ||
1041 | pr_debug("kfd: In func %s\n", __func__); | 981 | pr_debug("kfd: In func %s\n", __func__); |
1042 | 982 | ||
@@ -1073,18 +1013,13 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, | |||
1073 | qpd->sh_mem_ape1_limit = limit >> 16; | 1013 | qpd->sh_mem_ape1_limit = limit >> 16; |
1074 | } | 1014 | } |
1075 | 1015 | ||
1076 | default_mtype = (default_policy == cache_policy_coherent) ? | 1016 | retval = dqm->ops_asic_specific.set_cache_memory_policy( |
1077 | MTYPE_NONCACHED : | 1017 | dqm, |
1078 | MTYPE_CACHED; | 1018 | qpd, |
1079 | 1019 | default_policy, | |
1080 | ape1_mtype = (alternate_policy == cache_policy_coherent) ? | 1020 | alternate_policy, |
1081 | MTYPE_NONCACHED : | 1021 | alternate_aperture_base, |
1082 | MTYPE_CACHED; | 1022 | alternate_aperture_size); |
1083 | |||
1084 | qpd->sh_mem_config = (qpd->sh_mem_config & PTR32) | ||
1085 | | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | ||
1086 | | DEFAULT_MTYPE(default_mtype) | ||
1087 | | APE1_MTYPE(ape1_mtype); | ||
1088 | 1023 | ||
1089 | if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0)) | 1024 | if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0)) |
1090 | program_sh_mem_settings(dqm, qpd); | 1025 | program_sh_mem_settings(dqm, qpd); |
@@ -1094,7 +1029,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm, | |||
1094 | qpd->sh_mem_ape1_limit); | 1029 | qpd->sh_mem_ape1_limit); |
1095 | 1030 | ||
1096 | mutex_unlock(&dqm->lock); | 1031 | mutex_unlock(&dqm->lock); |
1097 | return true; | 1032 | return retval; |
1098 | 1033 | ||
1099 | out: | 1034 | out: |
1100 | mutex_unlock(&dqm->lock); | 1035 | mutex_unlock(&dqm->lock); |
@@ -1107,6 +1042,8 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) | |||
1107 | 1042 | ||
1108 | BUG_ON(!dev); | 1043 | BUG_ON(!dev); |
1109 | 1044 | ||
1045 | pr_debug("kfd: loading device queue manager\n"); | ||
1046 | |||
1110 | dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL); | 1047 | dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL); |
1111 | if (!dqm) | 1048 | if (!dqm) |
1112 | return NULL; | 1049 | return NULL; |
@@ -1149,6 +1086,13 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev) | |||
1149 | break; | 1086 | break; |
1150 | } | 1087 | } |
1151 | 1088 | ||
1089 | switch (dev->device_info->asic_family) { | ||
1090 | case CHIP_CARRIZO: | ||
1091 | device_queue_manager_init_vi(&dqm->ops_asic_specific); | ||
1092 | case CHIP_KAVERI: | ||
1093 | device_queue_manager_init_cik(&dqm->ops_asic_specific); | ||
1094 | } | ||
1095 | |||
1152 | if (dqm->ops.initialize(dqm) != 0) { | 1096 | if (dqm->ops.initialize(dqm) != 0) { |
1153 | kfree(dqm); | 1097 | kfree(dqm); |
1154 | return NULL; | 1098 | return NULL; |
@@ -1164,4 +1108,3 @@ void device_queue_manager_uninit(struct device_queue_manager *dqm) | |||
1164 | dqm->ops.uninitialize(dqm); | 1108 | dqm->ops.uninitialize(dqm); |
1165 | kfree(dqm); | 1109 | kfree(dqm); |
1166 | } | 1110 | } |
1167 | |||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 72d2ca056e19..19347956eeb9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | |||
@@ -134,6 +134,7 @@ struct device_queue_manager_ops { | |||
134 | 134 | ||
135 | struct device_queue_manager { | 135 | struct device_queue_manager { |
136 | struct device_queue_manager_ops ops; | 136 | struct device_queue_manager_ops ops; |
137 | struct device_queue_manager_ops ops_asic_specific; | ||
137 | 138 | ||
138 | struct mqd_manager *mqds[KFD_MQD_TYPE_MAX]; | 139 | struct mqd_manager *mqds[KFD_MQD_TYPE_MAX]; |
139 | struct packet_manager packets; | 140 | struct packet_manager packets; |
@@ -155,6 +156,14 @@ struct device_queue_manager { | |||
155 | bool active_runlist; | 156 | bool active_runlist; |
156 | }; | 157 | }; |
157 | 158 | ||
158 | 159 | void device_queue_manager_init_cik(struct device_queue_manager_ops *ops); | |
160 | void device_queue_manager_init_vi(struct device_queue_manager_ops *ops); | ||
161 | void program_sh_mem_settings(struct device_queue_manager *dqm, | ||
162 | struct qcm_process_device *qpd); | ||
163 | inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *qpd); | ||
164 | inline unsigned int get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd); | ||
165 | int init_pipelines(struct device_queue_manager *dqm, | ||
166 | unsigned int pipes_num, unsigned int first_pipe); | ||
167 | inline unsigned int get_pipes_num(struct device_queue_manager *dqm); | ||
159 | 168 | ||
160 | #endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */ | 169 | #endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */ |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c new file mode 100644 index 000000000000..6b072466e2a6 --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "kfd_device_queue_manager.h" | ||
25 | #include "cik_regs.h" | ||
26 | |||
27 | static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, | ||
28 | struct qcm_process_device *qpd, | ||
29 | enum cache_policy default_policy, | ||
30 | enum cache_policy alternate_policy, | ||
31 | void __user *alternate_aperture_base, | ||
32 | uint64_t alternate_aperture_size); | ||
33 | static int register_process_cik(struct device_queue_manager *dqm, | ||
34 | struct qcm_process_device *qpd); | ||
35 | static int initialize_cpsch_cik(struct device_queue_manager *dqm); | ||
36 | |||
37 | void device_queue_manager_init_cik(struct device_queue_manager_ops *ops) | ||
38 | { | ||
39 | ops->set_cache_memory_policy = set_cache_memory_policy_cik; | ||
40 | ops->register_process = register_process_cik; | ||
41 | ops->initialize = initialize_cpsch_cik; | ||
42 | } | ||
43 | |||
44 | static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) | ||
45 | { | ||
46 | /* In 64-bit mode, we can only control the top 3 bits of the LDS, | ||
47 | * scratch and GPUVM apertures. | ||
48 | * The hardware fills in the remaining 59 bits according to the | ||
49 | * following pattern: | ||
50 | * LDS: X0000000'00000000 - X0000001'00000000 (4GB) | ||
51 | * Scratch: X0000001'00000000 - X0000002'00000000 (4GB) | ||
52 | * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB) | ||
53 | * | ||
54 | * (where X/Y is the configurable nybble with the low-bit 0) | ||
55 | * | ||
56 | * LDS and scratch will have the same top nybble programmed in the | ||
57 | * top 3 bits of SH_MEM_BASES.PRIVATE_BASE. | ||
58 | * GPUVM can have a different top nybble programmed in the | ||
59 | * top 3 bits of SH_MEM_BASES.SHARED_BASE. | ||
60 | * We don't bother to support different top nybbles | ||
61 | * for LDS/Scratch and GPUVM. | ||
62 | */ | ||
63 | |||
64 | BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE || | ||
65 | top_address_nybble == 0); | ||
66 | |||
67 | return PRIVATE_BASE(top_address_nybble << 12) | | ||
68 | SHARED_BASE(top_address_nybble << 12); | ||
69 | } | ||
70 | |||
71 | static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm, | ||
72 | struct qcm_process_device *qpd, | ||
73 | enum cache_policy default_policy, | ||
74 | enum cache_policy alternate_policy, | ||
75 | void __user *alternate_aperture_base, | ||
76 | uint64_t alternate_aperture_size) | ||
77 | { | ||
78 | uint32_t default_mtype; | ||
79 | uint32_t ape1_mtype; | ||
80 | |||
81 | default_mtype = (default_policy == cache_policy_coherent) ? | ||
82 | MTYPE_NONCACHED : | ||
83 | MTYPE_CACHED; | ||
84 | |||
85 | ape1_mtype = (alternate_policy == cache_policy_coherent) ? | ||
86 | MTYPE_NONCACHED : | ||
87 | MTYPE_CACHED; | ||
88 | |||
89 | qpd->sh_mem_config = (qpd->sh_mem_config & PTR32) | ||
90 | | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | ||
91 | | DEFAULT_MTYPE(default_mtype) | ||
92 | | APE1_MTYPE(ape1_mtype); | ||
93 | |||
94 | return true; | ||
95 | } | ||
96 | |||
97 | static int register_process_cik(struct device_queue_manager *dqm, | ||
98 | struct qcm_process_device *qpd) | ||
99 | { | ||
100 | struct kfd_process_device *pdd; | ||
101 | unsigned int temp; | ||
102 | |||
103 | BUG_ON(!dqm || !qpd); | ||
104 | |||
105 | pdd = qpd_to_pdd(qpd); | ||
106 | |||
107 | /* check if sh_mem_config register already configured */ | ||
108 | if (qpd->sh_mem_config == 0) { | ||
109 | qpd->sh_mem_config = | ||
110 | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) | | ||
111 | DEFAULT_MTYPE(MTYPE_NONCACHED) | | ||
112 | APE1_MTYPE(MTYPE_NONCACHED); | ||
113 | qpd->sh_mem_ape1_limit = 0; | ||
114 | qpd->sh_mem_ape1_base = 0; | ||
115 | } | ||
116 | |||
117 | if (qpd->pqm->process->is_32bit_user_mode) { | ||
118 | temp = get_sh_mem_bases_32(pdd); | ||
119 | qpd->sh_mem_bases = SHARED_BASE(temp); | ||
120 | qpd->sh_mem_config |= PTR32; | ||
121 | } else { | ||
122 | temp = get_sh_mem_bases_nybble_64(pdd); | ||
123 | qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); | ||
124 | } | ||
125 | |||
126 | pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n", | ||
127 | qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int initialize_cpsch_cik(struct device_queue_manager *dqm) | ||
133 | { | ||
134 | return init_pipelines(dqm, get_pipes_num(dqm), 0); | ||
135 | } | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c new file mode 100644 index 000000000000..20553dcd257d --- /dev/null +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright 2014 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include "kfd_device_queue_manager.h" | ||
25 | |||
26 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, | ||
27 | struct qcm_process_device *qpd, | ||
28 | enum cache_policy default_policy, | ||
29 | enum cache_policy alternate_policy, | ||
30 | void __user *alternate_aperture_base, | ||
31 | uint64_t alternate_aperture_size); | ||
32 | static int register_process_vi(struct device_queue_manager *dqm, | ||
33 | struct qcm_process_device *qpd); | ||
34 | static int initialize_cpsch_vi(struct device_queue_manager *dqm); | ||
35 | |||
36 | void device_queue_manager_init_vi(struct device_queue_manager_ops *ops) | ||
37 | { | ||
38 | pr_warn("amdkfd: VI DQM is not currently supported\n"); | ||
39 | |||
40 | ops->set_cache_memory_policy = set_cache_memory_policy_vi; | ||
41 | ops->register_process = register_process_vi; | ||
42 | ops->initialize = initialize_cpsch_vi; | ||
43 | } | ||
44 | |||
45 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, | ||
46 | struct qcm_process_device *qpd, | ||
47 | enum cache_policy default_policy, | ||
48 | enum cache_policy alternate_policy, | ||
49 | void __user *alternate_aperture_base, | ||
50 | uint64_t alternate_aperture_size) | ||
51 | { | ||
52 | return false; | ||
53 | } | ||
54 | |||
55 | static int register_process_vi(struct device_queue_manager *dqm, | ||
56 | struct qcm_process_device *qpd) | ||
57 | { | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | static int initialize_cpsch_vi(struct device_queue_manager *dqm) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||