| 1 | |
| 2 | * Copyright 2022 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 | #ifndef AMDGPU_XCP_H
|
| 25 | #define AMDGPU_XCP_H
|
| 26 |
|
| 27 | #include <linux/pci.h>
|
| 28 | #include <linux/xarray.h>
|
| 29 |
|
| 30 | #include "amdgpu_ctx.h"
|
| 31 |
|
| 32 | #define MAX_XCP 8
|
| 33 |
|
| 34 | #define AMDGPU_XCP_MODE_NONE -1
|
| 35 | #define AMDGPU_XCP_MODE_TRANS -2
|
| 36 |
|
| 37 | #define AMDGPU_XCP_FL_NONE 0
|
| 38 | #define AMDGPU_XCP_FL_LOCKED (1 << 0)
|
| 39 |
|
| 40 | #define AMDGPU_XCP_NO_PARTITION (~0)
|
| 41 |
|
| 42 | #define AMDGPU_XCP_OPS_KFD (1 << 0)
|
| 43 |
|
| 44 | #define XCP_INST_MASK(num_inst, xcp_id) \
|
| 45 | (num_inst ? GENMASK(num_inst - 1, 0) << (xcp_id * num_inst) : 0)
|
| 46 |
|
| 47 | struct amdgpu_fpriv;
|
| 48 |
|
| 49 | enum AMDGPU_XCP_IP_BLOCK {
|
| 50 | AMDGPU_XCP_GFXHUB,
|
| 51 | AMDGPU_XCP_GFX,
|
| 52 | AMDGPU_XCP_SDMA,
|
| 53 | AMDGPU_XCP_VCN,
|
| 54 | AMDGPU_XCP_MAX_BLOCKS
|
| 55 | };
|
| 56 |
|
| 57 | enum AMDGPU_XCP_STATE {
|
| 58 | AMDGPU_XCP_PREPARE_SUSPEND,
|
| 59 | AMDGPU_XCP_SUSPEND,
|
| 60 | AMDGPU_XCP_PREPARE_RESUME,
|
| 61 | AMDGPU_XCP_RESUME,
|
| 62 | };
|
| 63 |
|
| 64 | enum amdgpu_xcp_res_id {
|
| 65 | AMDGPU_XCP_RES_XCC,
|
| 66 | AMDGPU_XCP_RES_DMA,
|
| 67 | AMDGPU_XCP_RES_DEC,
|
| 68 | AMDGPU_XCP_RES_JPEG,
|
| 69 | AMDGPU_XCP_RES_MAX,
|
| 70 | };
|
| 71 |
|
| 72 | struct amdgpu_xcp_res_details {
|
| 73 | enum amdgpu_xcp_res_id id;
|
| 74 | u8 num_inst;
|
| 75 | u8 num_shared;
|
| 76 | struct kobject kobj;
|
| 77 | };
|
| 78 |
|
| 79 | struct amdgpu_xcp_cfg {
|
| 80 | u8 mode;
|
| 81 | struct amdgpu_xcp_res_details xcp_res[AMDGPU_XCP_RES_MAX];
|
| 82 | u8 num_res;
|
| 83 | struct amdgpu_xcp_mgr *xcp_mgr;
|
| 84 | struct kobject kobj;
|
| 85 | u16 compatible_nps_modes;
|
| 86 | };
|
| 87 |
|
| 88 | struct amdgpu_xcp_ip_funcs {
|
| 89 | int (*prepare_suspend)(void *handle, uint32_t inst_mask);
|
| 90 | int (*suspend)(void *handle, uint32_t inst_mask);
|
| 91 | int (*prepare_resume)(void *handle, uint32_t inst_mask);
|
| 92 | int (*resume)(void *handle, uint32_t inst_mask);
|
| 93 | };
|
| 94 |
|
| 95 | struct amdgpu_xcp_ip {
|
| 96 | struct amdgpu_xcp_ip_funcs *ip_funcs;
|
| 97 | uint32_t inst_mask;
|
| 98 |
|
| 99 | enum AMDGPU_XCP_IP_BLOCK ip_id;
|
| 100 | bool valid;
|
| 101 | };
|
| 102 |
|
| 103 | struct amdgpu_xcp {
|
| 104 | struct amdgpu_xcp_ip ip[AMDGPU_XCP_MAX_BLOCKS];
|
| 105 |
|
| 106 | uint8_t id;
|
| 107 | uint8_t mem_id;
|
| 108 | bool valid;
|
| 109 | atomic_t ref_cnt;
|
| 110 | struct drm_device *ddev;
|
| 111 | struct drm_device *rdev;
|
| 112 | struct drm_device *pdev;
|
| 113 | struct drm_driver *driver;
|
| 114 | struct drm_vma_offset_manager *vma_offset_manager;
|
| 115 | struct amdgpu_sched gpu_sched[AMDGPU_HW_IP_NUM][AMDGPU_RING_PRIO_MAX];
|
| 116 | struct amdgpu_xcp_mgr *xcp_mgr;
|
| 117 | struct kobject kobj;
|
| 118 | uint64_t unique_id;
|
| 119 | };
|
| 120 |
|
| 121 | struct amdgpu_xcp_mgr {
|
| 122 | struct amdgpu_device *adev;
|
| 123 | struct mutex xcp_lock;
|
| 124 | struct amdgpu_xcp_mgr_funcs *funcs;
|
| 125 |
|
| 126 | struct amdgpu_xcp xcp[MAX_XCP];
|
| 127 | uint8_t num_xcps;
|
| 128 | int8_t mode;
|
| 129 |
|
| 130 |
|
| 131 | unsigned int num_xcp_per_mem_partition;
|
| 132 | struct amdgpu_xcp_cfg *xcp_cfg;
|
| 133 | uint32_t supp_xcp_modes;
|
| 134 | uint32_t avail_xcp_modes;
|
| 135 |
|
| 136 | uint32_t mem_alloc_mode;
|
| 137 | };
|
| 138 |
|
| 139 | struct amdgpu_xcp_mgr_funcs {
|
| 140 | int (*switch_partition_mode)(struct amdgpu_xcp_mgr *xcp_mgr, int mode,
|
| 141 | int *num_xcps);
|
| 142 | int (*query_partition_mode)(struct amdgpu_xcp_mgr *xcp_mgr);
|
| 143 | int (*get_ip_details)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id,
|
| 144 | enum AMDGPU_XCP_IP_BLOCK ip_id,
|
| 145 | struct amdgpu_xcp_ip *ip);
|
| 146 | int (*get_xcp_mem_id)(struct amdgpu_xcp_mgr *xcp_mgr,
|
| 147 | struct amdgpu_xcp *xcp, uint8_t *mem_id);
|
| 148 | int (*get_xcp_res_info)(struct amdgpu_xcp_mgr *xcp_mgr,
|
| 149 | int mode,
|
| 150 | struct amdgpu_xcp_cfg *xcp_cfg);
|
| 151 | int (*prepare_suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 152 | int (*suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 153 | int (*prepare_resume)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 154 | int (*resume)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 155 | };
|
| 156 |
|
| 157 | int amdgpu_xcp_prepare_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 158 | int amdgpu_xcp_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 159 | int amdgpu_xcp_prepare_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 160 | int amdgpu_xcp_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id);
|
| 161 |
|
| 162 | int amdgpu_xcp_mgr_init(struct amdgpu_device *adev, int init_mode,
|
| 163 | int init_xcps, struct amdgpu_xcp_mgr_funcs *xcp_funcs);
|
| 164 | int amdgpu_xcp_init(struct amdgpu_xcp_mgr *xcp_mgr, int num_xcps, int mode);
|
| 165 | int amdgpu_xcp_query_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, u32 flags);
|
| 166 | int amdgpu_xcp_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, int mode);
|
| 167 | int amdgpu_xcp_restore_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr);
|
| 168 | int amdgpu_xcp_get_partition(struct amdgpu_xcp_mgr *xcp_mgr,
|
| 169 | enum AMDGPU_XCP_IP_BLOCK ip, int instance);
|
| 170 |
|
| 171 | int amdgpu_xcp_get_inst_details(struct amdgpu_xcp *xcp,
|
| 172 | enum AMDGPU_XCP_IP_BLOCK ip,
|
| 173 | uint32_t *inst_mask);
|
| 174 |
|
| 175 | int amdgpu_xcp_dev_register(struct amdgpu_device *adev,
|
| 176 | const struct pci_device_id *ent);
|
| 177 | void amdgpu_xcp_dev_unplug(struct amdgpu_device *adev);
|
| 178 | int amdgpu_xcp_open_device(struct amdgpu_device *adev,
|
| 179 | struct amdgpu_fpriv *fpriv,
|
| 180 | struct drm_file *file_priv);
|
| 181 | void amdgpu_xcp_release_sched(struct amdgpu_device *adev,
|
| 182 | struct amdgpu_ctx_entity *entity);
|
| 183 | int amdgpu_xcp_select_scheds(struct amdgpu_device *adev,
|
| 184 | u32 hw_ip, u32 hw_prio,
|
| 185 | struct amdgpu_fpriv *fpriv,
|
| 186 | unsigned int *num_scheds,
|
| 187 | struct drm_gpu_scheduler ***scheds);
|
| 188 | void amdgpu_xcp_update_supported_modes(struct amdgpu_xcp_mgr *xcp_mgr);
|
| 189 | int amdgpu_xcp_update_partition_sched_list(struct amdgpu_device *adev);
|
| 190 | int amdgpu_xcp_pre_partition_switch(struct amdgpu_xcp_mgr *xcp_mgr, u32 flags);
|
| 191 | int amdgpu_xcp_post_partition_switch(struct amdgpu_xcp_mgr *xcp_mgr, u32 flags);
|
| 192 | void amdgpu_xcp_sysfs_init(struct amdgpu_device *adev);
|
| 193 | void amdgpu_xcp_sysfs_fini(struct amdgpu_device *adev);
|
| 194 |
|
| 195 | static inline int amdgpu_xcp_get_num_xcp(struct amdgpu_xcp_mgr *xcp_mgr)
|
| 196 | {
|
| 197 | if (!xcp_mgr)
|
| 198 | return 1;
|
| 199 | else
|
| 200 | return xcp_mgr->num_xcps;
|
| 201 | }
|
| 202 |
|
| 203 | static inline struct amdgpu_xcp *
|
| 204 | amdgpu_get_next_xcp(struct amdgpu_xcp_mgr *xcp_mgr, int *from)
|
| 205 | {
|
| 206 | if (!xcp_mgr)
|
| 207 | return NULL;
|
| 208 |
|
| 209 | while (*from < MAX_XCP) {
|
| 210 | if (xcp_mgr->xcp[*from].valid)
|
| 211 | return &xcp_mgr->xcp[*from];
|
| 212 | ++(*from);
|
| 213 | }
|
| 214 |
|
| 215 | return NULL;
|
| 216 | }
|
| 217 |
|
| 218 | #define for_each_xcp(xcp_mgr, xcp, i) \
|
| 219 | for (i = 0, xcp = amdgpu_get_next_xcp(xcp_mgr, &i); xcp; \
|
| 220 | ++i, xcp = amdgpu_get_next_xcp(xcp_mgr, &i))
|
| 221 |
|
| 222 | #endif
|