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
  28static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
  29                                   struct qcm_process_device *qpd,
  30                                   enum cache_policy default_policy,
  31                                   enum cache_policy alternate_policy,
  32                                   void __user *alternate_aperture_base,
  33                                   uint64_t alternate_aperture_size);
  34static int register_process_cik(struct device_queue_manager *dqm,
  35                                        struct qcm_process_device *qpd);
  36static int initialize_cpsch_cik(struct device_queue_manager *dqm);
  37static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
  38                                struct qcm_process_device *qpd);
  39
  40void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops)
  41{
  42        ops->set_cache_memory_policy = set_cache_memory_policy_cik;
  43        ops->register_process = register_process_cik;
  44        ops->initialize = initialize_cpsch_cik;
  45        ops->init_sdma_vm = init_sdma_vm;
  46}
  47
  48static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
  49{
  50        /* In 64-bit mode, we can only control the top 3 bits of the LDS,
  51         * scratch and GPUVM apertures.
  52         * The hardware fills in the remaining 59 bits according to the
  53         * following pattern:
  54         * LDS:         X0000000'00000000 - X0000001'00000000 (4GB)
  55         * Scratch:     X0000001'00000000 - X0000002'00000000 (4GB)
  56         * GPUVM:       Y0010000'00000000 - Y0020000'00000000 (1TB)
  57         *
  58         * (where X/Y is the configurable nybble with the low-bit 0)
  59         *
  60         * LDS and scratch will have the same top nybble programmed in the
  61         * top 3 bits of SH_MEM_BASES.PRIVATE_BASE.
  62         * GPUVM can have a different top nybble programmed in the
  63         * top 3 bits of SH_MEM_BASES.SHARED_BASE.
  64         * We don't bother to support different top nybbles
  65         * for LDS/Scratch and GPUVM.
  66         */
  67
  68        BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
  69                top_address_nybble == 0);
  70
  71        return PRIVATE_BASE(top_address_nybble << 12) |
  72                        SHARED_BASE(top_address_nybble << 12);
  73}
  74
  75static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
  76                                   struct qcm_process_device *qpd,
  77                                   enum cache_policy default_policy,
  78                                   enum cache_policy alternate_policy,
  79                                   void __user *alternate_aperture_base,
  80                                   uint64_t alternate_aperture_size)
  81{
  82        uint32_t default_mtype;
  83        uint32_t ape1_mtype;
  84
  85        default_mtype = (default_policy == cache_policy_coherent) ?
  86                        MTYPE_NONCACHED :
  87                        MTYPE_CACHED;
  88
  89        ape1_mtype = (alternate_policy == cache_policy_coherent) ?
  90                        MTYPE_NONCACHED :
  91                        MTYPE_CACHED;
  92
  93        qpd->sh_mem_config = (qpd->sh_mem_config & PTR32)
  94                        | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
  95                        | DEFAULT_MTYPE(default_mtype)
  96                        | APE1_MTYPE(ape1_mtype);
  97
  98        return true;
  99}
 100
 101static int register_process_cik(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        return 0;
 134}
 135
 136static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
 137                                struct qcm_process_device *qpd)
 138{
 139        uint32_t value = (1 << SDMA0_RLC0_VIRTUAL_ADDR__ATC__SHIFT);
 140
 141        if (q->process->is_32bit_user_mode)
 142                value |= (1 << SDMA0_RLC0_VIRTUAL_ADDR__PTR32__SHIFT) |
 143                                get_sh_mem_bases_32(qpd_to_pdd(qpd));
 144        else
 145                value |= ((get_sh_mem_bases_nybble_64(qpd_to_pdd(qpd))) <<
 146                                SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE__SHIFT) &
 147                                SDMA0_RLC0_VIRTUAL_ADDR__SHARED_BASE_MASK;
 148
 149        q->properties.sdma_vm_addr = value;
 150}
 151
 152static int initialize_cpsch_cik(struct device_queue_manager *dqm)
 153{
 154        return init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm));
 155}
 156