linux/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
<<
>>
Prefs
   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#include "oss/oss_2_4_sh_mask.h"
  27#include "gca/gfx_7_2_sh_mask.h"
  28
  29static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
  30                                   struct qcm_process_device *qpd,
  31                                   enum cache_policy default_policy,
  32                                   enum cache_policy alternate_policy,
  33                                   void __user *alternate_aperture_base,
  34                                   uint64_t alternate_aperture_size);
  35static int update_qpd_cik(struct device_queue_manager *dqm,
  36                                        struct qcm_process_device *qpd);
  37static int update_qpd_cik_hawaii(struct device_queue_manager *dqm,
  38                                        struct qcm_process_device *qpd);
  39static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
  40                                struct qcm_process_device *qpd);
  41static void init_sdma_vm_hawaii(struct device_queue_manager *dqm,
  42                                struct queue *q,
  43                                struct qcm_process_device *qpd);
  44
  45void device_queue_manager_init_cik(
  46                struct device_queue_manager_asic_ops *asic_ops)
  47{
  48        asic_ops->set_cache_memory_policy = set_cache_memory_policy_cik;
  49        asic_ops->update_qpd = update_qpd_cik;
  50        asic_ops->init_sdma_vm = init_sdma_vm;
  51        asic_ops->mqd_manager_init = mqd_manager_init_cik;
  52}
  53
  54void device_queue_manager_init_cik_hawaii(
  55                struct device_queue_manager_asic_ops *asic_ops)
  56{
  57        asic_ops->set_cache_memory_policy = set_cache_memory_policy_cik;
  58        asic_ops->update_qpd = update_qpd_cik_hawaii;
  59        asic_ops->init_sdma_vm = init_sdma_vm_hawaii;
  60        asic_ops->mqd_manager_init = mqd_manager_init_cik_hawaii;
  61}
  62
  63static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
  64{
  65        /* In 64-bit mode, we can only control the top 3 bits of the LDS,
  66         * scratch and GPUVM apertures.
  67         * The hardware fills in the remaining 59 bits according to the
  68         * following pattern:
  69         * LDS:         X0000000'00000000 - X0000001'00000000 (4GB)
  70         * Scratch:     X0000001'00000000 - X0000002'00000000 (4GB)
  71         * GPUVM:       Y0010000'00000000 - Y0020000'00000000 (1TB)
  72         *
  73         * (where X/Y is the configurable nybble with the low-bit 0)
  74         *
  75         * LDS and scratch will have the same top nybble programmed in the
  76         * top 3 bits of SH_MEM_BASES.PRIVATE_BASE.
  77         * GPUVM can have a different top nybble programmed in the
  78         * top 3 bits of SH_MEM_BASES.SHARED_BASE.
  79         * We don't bother to support different top nybbles
  80         * for LDS/Scratch and GPUVM.
  81         */
  82
  83        WARN_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
  84                top_address_nybble == 0);
  85
  86        return PRIVATE_BASE(top_address_nybble << 12) |
  87                        SHARED_BASE(top_address_nybble << 12);
  88}
  89
  90static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
  91                                   struct qcm_process_device *qpd,
  92                                   enum cache_policy default_policy,
  93                                   enum cache_policy alternate_policy,
  94                                   void __user *alternate_aperture_base,
  95                                   uint64_t alternate_aperture_size)
  96{
  97        uint32_t default_mtype;
  98        uint32_t ape1_mtype;
  99
 100        default_mtype = (default_policy == cache_policy_coherent) ?
 101                        MTYPE_NONCACHED :
 102                        MTYPE_CACHED;
 103
 104        ape1_mtype = (alternate_policy == cache_policy_coherent) ?
 105                        MTYPE_NONCACHED :
 106                        MTYPE_CACHED;
 107
 108        qpd->sh_mem_config = (qpd->sh_mem_config & PTR32)
 109                        | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
 110                        | DEFAULT_MTYPE(default_mtype)
 111                        | APE1_MTYPE(ape1_mtype);
 112
 113        return true;
 114}
 115
 116static int update_qpd_cik(struct device_queue_manager *dqm,
 117                struct qcm_process_device *qpd)
 118{
 119        struct kfd_process_device *pdd;
 120        unsigned int temp;
 121
 122        pdd = qpd_to_pdd(qpd);
 123
 124        /* check if sh_mem_config register already configured */
 125        if (qpd->sh_mem_config == 0) {
 126                qpd->sh_mem_config =
 127                        ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) |
 128                        DEFAULT_MTYPE(MTYPE_NONCACHED) |
 129                        APE1_MTYPE(MTYPE_NONCACHED);
 130                qpd->sh_mem_ape1_limit = 0;
 131                qpd->sh_mem_ape1_base = 0;
 132        }
 133
 134        if (qpd->pqm->process->is_32bit_user_mode) {
 135                temp = get_sh_mem_bases_32(pdd);
 136                qpd->sh_mem_bases = SHARED_BASE(temp);
 137                qpd->sh_mem_config |= PTR32;
 138        } else {
 139                temp = get_sh_mem_bases_nybble_64(pdd);
 140                qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
 141                qpd->sh_mem_config |= 1  << SH_MEM_CONFIG__PRIVATE_ATC__SHIFT;
 142        }
 143
 144        pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
 145                qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
 146
 147        return 0;
 148}
 149
 150static int update_qpd_cik_hawaii(struct device_queue_manager *dqm,
 151                struct qcm_process_device *qpd)
 152{
 153        struct kfd_process_device *pdd;
 154        unsigned int temp;
 155
 156        pdd = qpd_to_pdd(qpd);
 157
 158        /* check if sh_mem_config register already configured */
 159        if (qpd->sh_mem_config == 0) {
 160                qpd->sh_mem_config =
 161                        ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) |
 162                        DEFAULT_MTYPE(MTYPE_NONCACHED) |
 163                        APE1_MTYPE(MTYPE_NONCACHED);
 164                qpd->sh_mem_ape1_limit = 0;
 165                qpd->sh_mem_ape1_base = 0;
 166        }
 167
 168        /* On dGPU we're always in GPUVM64 addressing mode with 64-bit
 169         * aperture addresses.
 170         */
 171        temp = get_sh_mem_bases_nybble_64(pdd);
 172        qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
 173
 174        pr_debug("is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
 175                qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
 176
 177        return 0;
 178}
 179
 180static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
 181                                struct qcm_process_device *qpd)
 182{
 183        uint32_t value = (1 << SDMA0_RLC0_VIRTUAL_ADDR__ATC__SHIFT);
 184
 185        if (q->process->is_32bit_user_mode)
 186                value |= (1 << SDMA0_RLC0_VIRTUAL_ADDR__PTR32__SHIFT) |
 187                                get_sh_mem_bases_32(qpd_to_pdd(qpd));
 188        else
 189                value |= ((get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd))) <<
 190                                SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE__SHIFT) &
 191                                SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE_MASK;
 192
 193        q->properties.sdma_vm_addr = value;
 194}
 195
 196static void init_sdma_vm_hawaii(struct device_queue_manager *dqm,
 197                                struct queue *q,
 198                                struct qcm_process_device *qpd)
 199{
 200        /* On dGPU we're always in GPUVM64 addressing mode with 64-bit
 201         * aperture addresses.
 202         */
 203        q->properties.sdma_vm_addr =
 204                ((get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd))) <<
 205                 SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE__SHIFT) &
 206                SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE_MASK;
 207}
 208