diff options
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c | 103 |
1 files changed, 99 insertions, 4 deletions
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 index 4c15212a3899..44c38e8e54d3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c | |||
| @@ -22,6 +22,10 @@ | |||
| 22 | */ | 22 | */ |
| 23 | 23 | ||
| 24 | #include "kfd_device_queue_manager.h" | 24 | #include "kfd_device_queue_manager.h" |
| 25 | #include "gca/gfx_8_0_enum.h" | ||
| 26 | #include "gca/gfx_8_0_sh_mask.h" | ||
| 27 | #include "gca/gfx_8_0_enum.h" | ||
| 28 | #include "oss/oss_3_0_sh_mask.h" | ||
| 25 | 29 | ||
| 26 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, | 30 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, |
| 27 | struct qcm_process_device *qpd, | 31 | struct qcm_process_device *qpd, |
| @@ -37,14 +41,40 @@ static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, | |||
| 37 | 41 | ||
| 38 | void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops) | 42 | void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops) |
| 39 | { | 43 | { |
| 40 | pr_warn("amdkfd: VI DQM is not currently supported\n"); | ||
| 41 | |||
| 42 | ops->set_cache_memory_policy = set_cache_memory_policy_vi; | 44 | ops->set_cache_memory_policy = set_cache_memory_policy_vi; |
| 43 | ops->register_process = register_process_vi; | 45 | ops->register_process = register_process_vi; |
| 44 | ops->initialize = initialize_cpsch_vi; | 46 | ops->initialize = initialize_cpsch_vi; |
| 45 | ops->init_sdma_vm = init_sdma_vm; | 47 | ops->init_sdma_vm = init_sdma_vm; |
| 46 | } | 48 | } |
| 47 | 49 | ||
| 50 | static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble) | ||
| 51 | { | ||
| 52 | /* In 64-bit mode, we can only control the top 3 bits of the LDS, | ||
| 53 | * scratch and GPUVM apertures. | ||
| 54 | * The hardware fills in the remaining 59 bits according to the | ||
| 55 | * following pattern: | ||
| 56 | * LDS: X0000000'00000000 - X0000001'00000000 (4GB) | ||
| 57 | * Scratch: X0000001'00000000 - X0000002'00000000 (4GB) | ||
| 58 | * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB) | ||
| 59 | * | ||
| 60 | * (where X/Y is the configurable nybble with the low-bit 0) | ||
| 61 | * | ||
| 62 | * LDS and scratch will have the same top nybble programmed in the | ||
| 63 | * top 3 bits of SH_MEM_BASES.PRIVATE_BASE. | ||
| 64 | * GPUVM can have a different top nybble programmed in the | ||
| 65 | * top 3 bits of SH_MEM_BASES.SHARED_BASE. | ||
| 66 | * We don't bother to support different top nybbles | ||
| 67 | * for LDS/Scratch and GPUVM. | ||
| 68 | */ | ||
| 69 | |||
| 70 | BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE || | ||
| 71 | top_address_nybble == 0); | ||
| 72 | |||
| 73 | return top_address_nybble << 12 | | ||
| 74 | (top_address_nybble << 12) << | ||
| 75 | SH_MEM_BASES__SHARED_BASE__SHIFT; | ||
| 76 | } | ||
| 77 | |||
| 48 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, | 78 | static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, |
| 49 | struct qcm_process_device *qpd, | 79 | struct qcm_process_device *qpd, |
| 50 | enum cache_policy default_policy, | 80 | enum cache_policy default_policy, |
| @@ -52,18 +82,83 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm, | |||
| 52 | void __user *alternate_aperture_base, | 82 | void __user *alternate_aperture_base, |
| 53 | uint64_t alternate_aperture_size) | 83 | uint64_t alternate_aperture_size) |
| 54 | { | 84 | { |
| 55 | return false; | 85 | uint32_t default_mtype; |
| 86 | uint32_t ape1_mtype; | ||
| 87 | |||
| 88 | default_mtype = (default_policy == cache_policy_coherent) ? | ||
| 89 | MTYPE_CC : | ||
| 90 | MTYPE_NC; | ||
| 91 | |||
| 92 | ape1_mtype = (alternate_policy == cache_policy_coherent) ? | ||
| 93 | MTYPE_CC : | ||
| 94 | MTYPE_NC; | ||
| 95 | |||
| 96 | qpd->sh_mem_config = (qpd->sh_mem_config & | ||
| 97 | SH_MEM_CONFIG__ADDRESS_MODE_MASK) | | ||
| 98 | SH_MEM_ALIGNMENT_MODE_UNALIGNED << | ||
| 99 | SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT | | ||
| 100 | default_mtype << SH_MEM_CONFIG__DEFAULT_MTYPE__SHIFT | | ||
| 101 | ape1_mtype << SH_MEM_CONFIG__APE1_MTYPE__SHIFT | | ||
| 102 | SH_MEM_CONFIG__PRIVATE_ATC_MASK; | ||
| 103 | |||
| 104 | return true; | ||
| 56 | } | 105 | } |
| 57 | 106 | ||
| 58 | static int register_process_vi(struct device_queue_manager *dqm, | 107 | static int register_process_vi(struct device_queue_manager *dqm, |
| 59 | struct qcm_process_device *qpd) | 108 | struct qcm_process_device *qpd) |
| 60 | { | 109 | { |
| 61 | return -1; | 110 | struct kfd_process_device *pdd; |
| 111 | unsigned int temp; | ||
| 112 | |||
| 113 | BUG_ON(!dqm || !qpd); | ||
| 114 | |||
| 115 | pdd = qpd_to_pdd(qpd); | ||
| 116 | |||
| 117 | /* check if sh_mem_config register already configured */ | ||
| 118 | if (qpd->sh_mem_config == 0) { | ||
| 119 | qpd->sh_mem_config = | ||
| 120 | SH_MEM_ALIGNMENT_MODE_UNALIGNED << | ||
| 121 | SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT | | ||
| 122 | MTYPE_CC << SH_MEM_CONFIG__DEFAULT_MTYPE__SHIFT | | ||
| 123 | MTYPE_CC << SH_MEM_CONFIG__APE1_MTYPE__SHIFT | | ||
| 124 | SH_MEM_CONFIG__PRIVATE_ATC_MASK; | ||
| 125 | |||
| 126 | qpd->sh_mem_ape1_limit = 0; | ||
| 127 | qpd->sh_mem_ape1_base = 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | if (qpd->pqm->process->is_32bit_user_mode) { | ||
| 131 | temp = get_sh_mem_bases_32(pdd); | ||
| 132 | qpd->sh_mem_bases = temp << SH_MEM_BASES__SHARED_BASE__SHIFT; | ||
| 133 | qpd->sh_mem_config |= SH_MEM_ADDRESS_MODE_HSA32 << | ||
| 134 | SH_MEM_CONFIG__ADDRESS_MODE__SHIFT; | ||
| 135 | } else { | ||
| 136 | temp = get_sh_mem_bases_nybble_64(pdd); | ||
| 137 | qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp); | ||
| 138 | qpd->sh_mem_config |= SH_MEM_ADDRESS_MODE_HSA64 << | ||
| 139 | SH_MEM_CONFIG__ADDRESS_MODE__SHIFT; | ||
| 140 | } | ||
| 141 | |||
| 142 | pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n", | ||
| 143 | qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases); | ||
| 144 | |||
| 145 | return 0; | ||
| 62 | } | 146 | } |
| 63 | 147 | ||
| 64 | static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, | 148 | static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q, |
| 65 | struct qcm_process_device *qpd) | 149 | struct qcm_process_device *qpd) |
| 66 | { | 150 | { |
| 151 | uint32_t value = (1 << SDMA0_RLC0_VIRTUAL_ADDR__ATC__SHIFT); | ||
| 152 | |||
| 153 | if (q->process->is_32bit_user_mode) | ||
| 154 | value |= (1 << SDMA0_RLC0_VIRTUAL_ADDR__PTR32__SHIFT) | | ||
| 155 | get_sh_mem_bases_32(qpd_to_pdd(qpd)); | ||
| 156 | else | ||
| 157 | value |= ((get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd))) << | ||
| 158 | SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE__SHIFT) && | ||
| 159 | SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE_MASK; | ||
| 160 | |||
| 161 | q->properties.sdma_vm_addr = value; | ||
| 67 | } | 162 | } |
| 68 | 163 | ||
| 69 | static int initialize_cpsch_vi(struct device_queue_manager *dqm) | 164 | static int initialize_cpsch_vi(struct device_queue_manager *dqm) |
