Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amdgpu: Add initial version of XCP routines

Within a device, an accelerator core partition can be constituted with
different IP instances. These partitions are spatial in nature. Number
of partitions which can exist at the same time depends on the 'partition
mode'. Add a manager entity which is responsible for switching between
different partition modes and maintaining partitions. It is also
responsible for suspend/resume of different partitions.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Lijo Lazar and committed by
Alex Deucher
75d16923 527c670e

+356 -3
+1 -1
drivers/gpu/drm/amd/amdgpu/Makefile
··· 60 60 amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \ 61 61 amdgpu_fw_attestation.o amdgpu_securedisplay.o \ 62 62 amdgpu_eeprom.o amdgpu_mca.o amdgpu_psp_ta.o amdgpu_lsdma.o \ 63 - amdgpu_ring_mux.o 63 + amdgpu_ring_mux.o amdgpu_xcp.o 64 64 65 65 amdgpu-$(CONFIG_PROC_FS) += amdgpu_fdinfo.o 66 66
+2
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 283 283 #define AMDGPU_SMARTSHIFT_MAX_BIAS (100) 284 284 #define AMDGPU_SMARTSHIFT_MIN_BIAS (-100) 285 285 286 + struct amdgpu_xcp_mgr; 286 287 struct amdgpu_device; 287 288 struct amdgpu_irq_src; 288 289 struct amdgpu_fpriv; ··· 766 765 struct amdgpu_acp acp; 767 766 #endif 768 767 struct amdgpu_hive_info *hive; 768 + struct amdgpu_xcp_mgr *xcp_mgr; 769 769 /* ASIC */ 770 770 enum amd_asic_type asic_type; 771 771 uint32_t family;
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
··· 61 61 AMDGPU_TPX_PARTITION_MODE = 2, 62 62 AMDGPU_QPX_PARTITION_MODE = 3, 63 63 AMDGPU_CPX_PARTITION_MODE = 4, 64 - AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE, 64 + AMDGPU_UNKNOWN_COMPUTE_PARTITION_MODE = -1, 65 65 }; 66 66 67 67 #define NUM_XCC(x) hweight16(x)
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_nbio.h
··· 96 96 void (*apply_l1_link_width_reconfig_wa)(struct amdgpu_device *adev); 97 97 void (*clear_doorbell_interrupt)(struct amdgpu_device *adev); 98 98 u32 (*get_rom_offset)(struct amdgpu_device *adev); 99 - u32 (*get_compute_partition_mode)(struct amdgpu_device *adev); 99 + int (*get_compute_partition_mode)(struct amdgpu_device *adev); 100 100 u32 (*get_memory_partition_mode)(struct amdgpu_device *adev); 101 101 void (*set_compute_partition_mode)(struct amdgpu_device *adev, 102 102 enum amdgpu_gfx_partition mode);
+244
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
··· 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 + #include "amdgpu.h" 24 + #include "amdgpu_xcp.h" 25 + 26 + static int __amdgpu_xcp_run(struct amdgpu_xcp_mgr *xcp_mgr, 27 + struct amdgpu_xcp_ip *xcp_ip, int xcp_state) 28 + { 29 + int (*run_func)(void *handle, uint32_t inst_mask); 30 + int ret = 0; 31 + 32 + if (!xcp_ip || !xcp_ip->valid || !xcp_ip->ip_funcs) 33 + return 0; 34 + 35 + run_func = NULL; 36 + 37 + switch (xcp_state) { 38 + case AMDGPU_XCP_PREPARE_SUSPEND: 39 + run_func = xcp_ip->ip_funcs->prepare_suspend; 40 + break; 41 + case AMDGPU_XCP_SUSPEND: 42 + run_func = xcp_ip->ip_funcs->suspend; 43 + break; 44 + case AMDGPU_XCP_PREPARE_RESUME: 45 + run_func = xcp_ip->ip_funcs->prepare_resume; 46 + break; 47 + case AMDGPU_XCP_RESUME: 48 + run_func = xcp_ip->ip_funcs->resume; 49 + break; 50 + } 51 + 52 + if (run_func) 53 + ret = run_func(xcp_mgr->adev, xcp_ip->inst_mask); 54 + 55 + return ret; 56 + } 57 + 58 + static int amdgpu_xcp_run_transition(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id, 59 + int state) 60 + { 61 + struct amdgpu_xcp_ip *xcp_ip; 62 + struct amdgpu_xcp *xcp; 63 + int i, ret; 64 + 65 + if (xcp_id > MAX_XCP || !xcp_mgr->xcp[xcp_id].valid) 66 + return -EINVAL; 67 + 68 + xcp = &xcp_mgr->xcp[xcp_id]; 69 + for (i = 0; i < AMDGPU_XCP_MAX_BLOCKS; ++i) { 70 + xcp_ip = &xcp->ip[i]; 71 + ret = __amdgpu_xcp_run(xcp_mgr, xcp_ip, state); 72 + if (ret) 73 + break; 74 + } 75 + 76 + return ret; 77 + } 78 + 79 + int amdgpu_xcp_prepare_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id) 80 + { 81 + return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, 82 + AMDGPU_XCP_PREPARE_SUSPEND); 83 + } 84 + 85 + int amdgpu_xcp_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id) 86 + { 87 + return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, AMDGPU_XCP_SUSPEND); 88 + } 89 + 90 + int amdgpu_xcp_prepare_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id) 91 + { 92 + return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, 93 + AMDGPU_XCP_PREPARE_RESUME); 94 + } 95 + 96 + int amdgpu_xcp_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id) 97 + { 98 + return amdgpu_xcp_run_transition(xcp_mgr, xcp_id, AMDGPU_XCP_RESUME); 99 + } 100 + 101 + static void __amdgpu_xcp_add_block(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id, 102 + struct amdgpu_xcp_ip *ip) 103 + { 104 + struct amdgpu_xcp *xcp; 105 + 106 + if (!ip) 107 + return; 108 + 109 + xcp = &xcp_mgr->xcp[xcp_id]; 110 + xcp->ip[ip->ip_id] = *ip; 111 + xcp->ip[ip->ip_id].valid = true; 112 + 113 + xcp->valid = true; 114 + } 115 + 116 + static int __amdgpu_xcp_init(struct amdgpu_xcp_mgr *xcp_mgr, int num_xcps) 117 + { 118 + struct amdgpu_xcp_ip ip; 119 + int i, j, ret; 120 + 121 + for (i = 0; i < MAX_XCP; ++i) 122 + xcp_mgr->xcp[i].valid = false; 123 + 124 + for (i = 0; i < num_xcps; ++i) { 125 + for (j = AMDGPU_XCP_GFXHUB; j < AMDGPU_XCP_MAX_BLOCKS; ++j) { 126 + ret = xcp_mgr->funcs->get_ip_details(xcp_mgr, i, j, 127 + &ip); 128 + if (ret) 129 + continue; 130 + 131 + __amdgpu_xcp_add_block(xcp_mgr, i, &ip); 132 + } 133 + } 134 + 135 + xcp_mgr->num_xcps = num_xcps; 136 + 137 + return 0; 138 + } 139 + 140 + int amdgpu_xcp_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, int mode) 141 + { 142 + int ret, num_xcps = 0; 143 + 144 + if (!xcp_mgr || mode == AMDGPU_XCP_MODE_NONE) 145 + return -EINVAL; 146 + 147 + if (xcp_mgr->mode == mode) 148 + return 0; 149 + 150 + if (!xcp_mgr->funcs || !xcp_mgr->funcs->switch_partition_mode) 151 + return 0; 152 + 153 + mutex_lock(&xcp_mgr->xcp_lock); 154 + 155 + ret = xcp_mgr->funcs->switch_partition_mode(xcp_mgr, mode, &num_xcps); 156 + 157 + if (ret) 158 + goto out; 159 + 160 + if (!num_xcps || num_xcps > MAX_XCP) { 161 + ret = -EINVAL; 162 + goto out; 163 + } 164 + 165 + xcp_mgr->mode = mode; 166 + __amdgpu_xcp_init(xcp_mgr, num_xcps); 167 + out: 168 + mutex_unlock(&xcp_mgr->xcp_lock); 169 + 170 + return ret; 171 + } 172 + 173 + int amdgpu_xcp_query_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr) 174 + { 175 + int mode; 176 + 177 + if (xcp_mgr->mode == AMDGPU_XCP_MODE_NONE) 178 + return xcp_mgr->mode; 179 + 180 + if (!xcp_mgr->funcs || !xcp_mgr->funcs->query_partition_mode) 181 + return xcp_mgr->mode; 182 + 183 + mutex_lock(&xcp_mgr->xcp_lock); 184 + mode = xcp_mgr->funcs->query_partition_mode(xcp_mgr); 185 + if (mode != xcp_mgr->mode) 186 + dev_WARN( 187 + xcp_mgr->adev->dev, 188 + "Cached partition mode %d not matching with device mode %d", 189 + xcp_mgr->mode, mode); 190 + 191 + mutex_unlock(&xcp_mgr->xcp_lock); 192 + 193 + return mode; 194 + } 195 + 196 + int amdgpu_xcp_mgr_init(struct amdgpu_device *adev, int init_mode, 197 + int init_num_xcps, 198 + struct amdgpu_xcp_mgr_funcs *xcp_funcs) 199 + { 200 + struct amdgpu_xcp_mgr *xcp_mgr; 201 + 202 + if (!xcp_funcs || !xcp_funcs->switch_partition_mode || 203 + !xcp_funcs->get_ip_details) 204 + return -EINVAL; 205 + 206 + xcp_mgr = kzalloc(sizeof(*xcp_mgr), GFP_KERNEL); 207 + 208 + if (!xcp_mgr) 209 + return -ENOMEM; 210 + 211 + xcp_mgr->adev = adev; 212 + xcp_mgr->funcs = xcp_funcs; 213 + xcp_mgr->mode = init_mode; 214 + mutex_init(&xcp_mgr->xcp_lock); 215 + 216 + if (init_mode != AMDGPU_XCP_MODE_NONE) 217 + __amdgpu_xcp_init(xcp_mgr, init_num_xcps); 218 + 219 + adev->xcp_mgr = xcp_mgr; 220 + 221 + return 0; 222 + } 223 + 224 + int amdgpu_xcp_get_partition(struct amdgpu_xcp_mgr *xcp_mgr, 225 + enum AMDGPU_XCP_IP_BLOCK ip, int instance) 226 + { 227 + struct amdgpu_xcp *xcp; 228 + int i, id_mask = 0; 229 + 230 + if (ip >= AMDGPU_XCP_MAX_BLOCKS) 231 + return -EINVAL; 232 + 233 + for (i = 0; i < xcp_mgr->num_xcps; ++i) { 234 + xcp = &xcp_mgr->xcp[i]; 235 + if ((xcp->valid) && (xcp->ip[ip].valid) && 236 + (xcp->ip[ip].inst_mask & BIT(instance))) 237 + id_mask |= BIT(i); 238 + } 239 + 240 + if (!id_mask) 241 + id_mask = -ENXIO; 242 + 243 + return id_mask; 244 + }
+107
drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
··· 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/xarray.h> 28 + 29 + #define MAX_XCP 8 30 + 31 + #define AMDGPU_XCP_MODE_NONE -1 32 + 33 + enum AMDGPU_XCP_IP_BLOCK { 34 + AMDGPU_XCP_GFXHUB, 35 + AMDGPU_XCP_GFX, 36 + AMDGPU_XCP_SDMA, 37 + AMDGPU_XCP_VCN, 38 + AMDGPU_XCP_MAX_BLOCKS 39 + }; 40 + 41 + enum AMDGPU_XCP_STATE { 42 + AMDGPU_XCP_PREPARE_SUSPEND, 43 + AMDGPU_XCP_SUSPEND, 44 + AMDGPU_XCP_PREPARE_RESUME, 45 + AMDGPU_XCP_RESUME, 46 + }; 47 + 48 + struct amdgpu_xcp_ip_funcs { 49 + int (*prepare_suspend)(void *handle, uint32_t inst_mask); 50 + int (*suspend)(void *handle, uint32_t inst_mask); 51 + int (*prepare_resume)(void *handle, uint32_t inst_mask); 52 + int (*resume)(void *handle, uint32_t inst_mask); 53 + }; 54 + 55 + struct amdgpu_xcp_ip { 56 + struct amdgpu_xcp_ip_funcs *ip_funcs; 57 + uint32_t inst_mask; 58 + 59 + enum AMDGPU_XCP_IP_BLOCK ip_id; 60 + bool valid; 61 + }; 62 + 63 + struct amdgpu_xcp { 64 + struct amdgpu_xcp_ip ip[AMDGPU_XCP_MAX_BLOCKS]; 65 + 66 + uint8_t id; 67 + uint8_t mem_node; 68 + bool valid; 69 + }; 70 + 71 + struct amdgpu_xcp_mgr { 72 + struct amdgpu_device *adev; 73 + struct mutex xcp_lock; 74 + struct amdgpu_xcp_mgr_funcs *funcs; 75 + 76 + struct amdgpu_xcp xcp[MAX_XCP]; 77 + uint8_t num_xcps; 78 + int8_t mode; 79 + }; 80 + 81 + struct amdgpu_xcp_mgr_funcs { 82 + int (*switch_partition_mode)(struct amdgpu_xcp_mgr *xcp_mgr, int mode, 83 + int *num_xcps); 84 + int (*query_partition_mode)(struct amdgpu_xcp_mgr *xcp_mgr); 85 + int (*get_ip_details)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id, 86 + enum AMDGPU_XCP_IP_BLOCK ip_id, 87 + struct amdgpu_xcp_ip *ip); 88 + 89 + int (*prepare_suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 90 + int (*suspend)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 91 + int (*prepare_resume)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 92 + int (*resume)(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 93 + }; 94 + 95 + int amdgpu_xcp_prepare_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 96 + int amdgpu_xcp_suspend(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 97 + int amdgpu_xcp_prepare_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 98 + int amdgpu_xcp_resume(struct amdgpu_xcp_mgr *xcp_mgr, int xcp_id); 99 + 100 + int amdgpu_xcp_mgr_init(struct amdgpu_device *adev, int init_mode, 101 + int init_xcps, struct amdgpu_xcp_mgr_funcs *xcp_funcs); 102 + int amdgpu_xcp_query_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr); 103 + int amdgpu_xcp_switch_partition_mode(struct amdgpu_xcp_mgr *xcp_mgr, int mode); 104 + int amdgpu_xcp_get_partition(struct amdgpu_xcp_mgr *xcp_mgr, 105 + enum AMDGPU_XCP_IP_BLOCK ip, int instance); 106 + 107 + #endif