| .. | .. |
|---|
| 24 | 24 | #ifndef AMDGPU_VIRT_H |
|---|
| 25 | 25 | #define AMDGPU_VIRT_H |
|---|
| 26 | 26 | |
|---|
| 27 | +#include "amdgv_sriovmsg.h" |
|---|
| 28 | + |
|---|
| 27 | 29 | #define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS (1 << 0) /* vBIOS is sr-iov ready */ |
|---|
| 28 | 30 | #define AMDGPU_SRIOV_CAPS_ENABLE_IOV (1 << 1) /* sr-iov is enabled on this GPU */ |
|---|
| 29 | 31 | #define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */ |
|---|
| 30 | 32 | #define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */ |
|---|
| 31 | 33 | #define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */ |
|---|
| 34 | +#define AMDGPU_VF_MMIO_ACCESS_PROTECT (1 << 5) /* MMIO write access is not allowed in sriov runtime */ |
|---|
| 35 | + |
|---|
| 36 | +/* all asic after AI use this offset */ |
|---|
| 37 | +#define mmRCC_IOV_FUNC_IDENTIFIER 0xDE5 |
|---|
| 38 | +/* tonga/fiji use this offset */ |
|---|
| 39 | +#define mmBIF_IOV_FUNC_IDENTIFIER 0x1503 |
|---|
| 40 | + |
|---|
| 41 | +enum amdgpu_sriov_vf_mode { |
|---|
| 42 | + SRIOV_VF_MODE_BARE_METAL = 0, |
|---|
| 43 | + SRIOV_VF_MODE_ONE_VF, |
|---|
| 44 | + SRIOV_VF_MODE_MULTI_VF, |
|---|
| 45 | +}; |
|---|
| 32 | 46 | |
|---|
| 33 | 47 | struct amdgpu_mm_table { |
|---|
| 34 | 48 | struct amdgpu_bo *bo; |
|---|
| .. | .. |
|---|
| 48 | 62 | uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; |
|---|
| 49 | 63 | }; |
|---|
| 50 | 64 | |
|---|
| 65 | +enum idh_request; |
|---|
| 66 | + |
|---|
| 51 | 67 | /** |
|---|
| 52 | 68 | * struct amdgpu_virt_ops - amdgpu device virt operations |
|---|
| 53 | 69 | */ |
|---|
| 54 | 70 | struct amdgpu_virt_ops { |
|---|
| 55 | 71 | int (*req_full_gpu)(struct amdgpu_device *adev, bool init); |
|---|
| 56 | 72 | int (*rel_full_gpu)(struct amdgpu_device *adev, bool init); |
|---|
| 73 | + int (*req_init_data)(struct amdgpu_device *adev); |
|---|
| 57 | 74 | int (*reset_gpu)(struct amdgpu_device *adev); |
|---|
| 58 | 75 | int (*wait_reset)(struct amdgpu_device *adev); |
|---|
| 59 | | - void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); |
|---|
| 76 | + void (*trans_msg)(struct amdgpu_device *adev, enum idh_request req, |
|---|
| 77 | + u32 data1, u32 data2, u32 data3); |
|---|
| 60 | 78 | }; |
|---|
| 61 | 79 | |
|---|
| 62 | 80 | /* |
|---|
| 63 | 81 | * Firmware Reserve Frame buffer |
|---|
| 64 | 82 | */ |
|---|
| 65 | 83 | struct amdgpu_virt_fw_reserve { |
|---|
| 66 | | - struct amdgim_pf2vf_info_header *p_pf2vf; |
|---|
| 67 | | - struct amdgim_vf2pf_info_header *p_vf2pf; |
|---|
| 84 | + struct amd_sriov_msg_pf2vf_info_header *p_pf2vf; |
|---|
| 85 | + struct amd_sriov_msg_vf2pf_info_header *p_vf2pf; |
|---|
| 68 | 86 | unsigned int checksum_key; |
|---|
| 69 | 87 | }; |
|---|
| 88 | + |
|---|
| 70 | 89 | /* |
|---|
| 90 | + * Legacy GIM header |
|---|
| 91 | + * |
|---|
| 71 | 92 | * Defination between PF and VF |
|---|
| 72 | 93 | * Structures forcibly aligned to 4 to keep the same style as PF. |
|---|
| 73 | 94 | */ |
|---|
| .. | .. |
|---|
| 83 | 104 | AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2, |
|---|
| 84 | 105 | /* VRAM LOST by GIM */ |
|---|
| 85 | 106 | AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4, |
|---|
| 107 | + /* MM bandwidth */ |
|---|
| 108 | + AMDGIM_FEATURE_GIM_MM_BW_MGR = 0x8, |
|---|
| 109 | + /* PP ONE VF MODE in GIM */ |
|---|
| 110 | + AMDGIM_FEATURE_PP_ONE_VF = (1 << 4), |
|---|
| 86 | 111 | }; |
|---|
| 87 | 112 | |
|---|
| 88 | | -struct amdgim_pf2vf_info_header { |
|---|
| 89 | | - /* the total structure size in byte. */ |
|---|
| 90 | | - uint32_t size; |
|---|
| 91 | | - /* version of this structure, written by the GIM */ |
|---|
| 92 | | - uint32_t version; |
|---|
| 93 | | -} __aligned(4); |
|---|
| 94 | | -struct amdgim_pf2vf_info_v1 { |
|---|
| 113 | +struct amdgim_pf2vf_info_v1 { |
|---|
| 95 | 114 | /* header contains size and version */ |
|---|
| 96 | | - struct amdgim_pf2vf_info_header header; |
|---|
| 115 | + struct amd_sriov_msg_pf2vf_info_header header; |
|---|
| 97 | 116 | /* max_width * max_height */ |
|---|
| 98 | 117 | unsigned int uvd_enc_max_pixels_count; |
|---|
| 99 | 118 | /* 16x16 pixels/sec, codec independent */ |
|---|
| .. | .. |
|---|
| 110 | 129 | unsigned int checksum; |
|---|
| 111 | 130 | } __aligned(4); |
|---|
| 112 | 131 | |
|---|
| 113 | | -struct amdgim_pf2vf_info_v2 { |
|---|
| 114 | | - /* header contains size and version */ |
|---|
| 115 | | - struct amdgim_pf2vf_info_header header; |
|---|
| 116 | | - /* use private key from mailbox 2 to create chueksum */ |
|---|
| 117 | | - uint32_t checksum; |
|---|
| 118 | | - /* The features flags of the GIM driver supports. */ |
|---|
| 119 | | - uint32_t feature_flags; |
|---|
| 120 | | - /* max_width * max_height */ |
|---|
| 121 | | - uint32_t uvd_enc_max_pixels_count; |
|---|
| 122 | | - /* 16x16 pixels/sec, codec independent */ |
|---|
| 123 | | - uint32_t uvd_enc_max_bandwidth; |
|---|
| 124 | | - /* max_width * max_height */ |
|---|
| 125 | | - uint32_t vce_enc_max_pixels_count; |
|---|
| 126 | | - /* 16x16 pixels/sec, codec independent */ |
|---|
| 127 | | - uint32_t vce_enc_max_bandwidth; |
|---|
| 128 | | - /* MEC FW position in kb from the start of VF visible frame buffer */ |
|---|
| 129 | | - uint64_t mecfw_kboffset; |
|---|
| 130 | | - /* MEC FW size in KB */ |
|---|
| 131 | | - uint32_t mecfw_ksize; |
|---|
| 132 | | - /* UVD FW position in kb from the start of VF visible frame buffer */ |
|---|
| 133 | | - uint64_t uvdfw_kboffset; |
|---|
| 134 | | - /* UVD FW size in KB */ |
|---|
| 135 | | - uint32_t uvdfw_ksize; |
|---|
| 136 | | - /* VCE FW position in kb from the start of VF visible frame buffer */ |
|---|
| 137 | | - uint64_t vcefw_kboffset; |
|---|
| 138 | | - /* VCE FW size in KB */ |
|---|
| 139 | | - uint32_t vcefw_ksize; |
|---|
| 140 | | - uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amdgim_pf2vf_info_header)/sizeof(uint32_t)), 3)]; |
|---|
| 141 | | -} __aligned(4); |
|---|
| 142 | | - |
|---|
| 143 | | - |
|---|
| 144 | | -struct amdgim_vf2pf_info_header { |
|---|
| 145 | | - /* the total structure size in byte. */ |
|---|
| 146 | | - uint32_t size; |
|---|
| 147 | | - /*version of this structure, written by the guest */ |
|---|
| 148 | | - uint32_t version; |
|---|
| 149 | | -} __aligned(4); |
|---|
| 150 | | - |
|---|
| 151 | 132 | struct amdgim_vf2pf_info_v1 { |
|---|
| 152 | 133 | /* header contains size and version */ |
|---|
| 153 | | - struct amdgim_vf2pf_info_header header; |
|---|
| 134 | + struct amd_sriov_msg_vf2pf_info_header header; |
|---|
| 154 | 135 | /* driver version */ |
|---|
| 155 | 136 | char driver_version[64]; |
|---|
| 156 | 137 | /* driver certification, 1=WHQL, 0=None */ |
|---|
| .. | .. |
|---|
| 180 | 161 | |
|---|
| 181 | 162 | struct amdgim_vf2pf_info_v2 { |
|---|
| 182 | 163 | /* header contains size and version */ |
|---|
| 183 | | - struct amdgim_vf2pf_info_header header; |
|---|
| 164 | + struct amd_sriov_msg_vf2pf_info_header header; |
|---|
| 184 | 165 | uint32_t checksum; |
|---|
| 185 | 166 | /* driver version */ |
|---|
| 186 | 167 | uint8_t driver_version[64]; |
|---|
| .. | .. |
|---|
| 206 | 187 | uint32_t uvd_enc_usage; |
|---|
| 207 | 188 | /* guest uvd engine usage percentage. 0xffff means N/A. */ |
|---|
| 208 | 189 | uint32_t uvd_enc_health; |
|---|
| 209 | | - uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amdgim_vf2pf_info_header)/sizeof(uint32_t)), 0)]; |
|---|
| 190 | + uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amd_sriov_msg_vf2pf_info_header)/sizeof(uint32_t)), 0)]; |
|---|
| 210 | 191 | } __aligned(4); |
|---|
| 211 | 192 | |
|---|
| 212 | | -#define AMDGPU_FW_VRAM_VF2PF_VER 2 |
|---|
| 213 | | -typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ; |
|---|
| 214 | | - |
|---|
| 215 | | -#define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \ |
|---|
| 216 | | - do { \ |
|---|
| 217 | | - ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \ |
|---|
| 218 | | - } while (0) |
|---|
| 219 | | - |
|---|
| 220 | | -#define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \ |
|---|
| 221 | | - do { \ |
|---|
| 222 | | - (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \ |
|---|
| 223 | | - } while (0) |
|---|
| 224 | | - |
|---|
| 225 | | -#define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \ |
|---|
| 226 | | - do { \ |
|---|
| 227 | | - if (!adev->virt.fw_reserve.p_pf2vf) \ |
|---|
| 228 | | - *(val) = 0; \ |
|---|
| 229 | | - else { \ |
|---|
| 230 | | - if (adev->virt.fw_reserve.p_pf2vf->version == 1) \ |
|---|
| 231 | | - *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \ |
|---|
| 232 | | - if (adev->virt.fw_reserve.p_pf2vf->version == 2) \ |
|---|
| 233 | | - *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \ |
|---|
| 234 | | - } \ |
|---|
| 235 | | - } while (0) |
|---|
| 193 | +struct amdgpu_virt_ras_err_handler_data { |
|---|
| 194 | + /* point to bad page records array */ |
|---|
| 195 | + struct eeprom_table_record *bps; |
|---|
| 196 | + /* point to reserved bo array */ |
|---|
| 197 | + struct amdgpu_bo **bps_bo; |
|---|
| 198 | + /* the count of entries */ |
|---|
| 199 | + int count; |
|---|
| 200 | + /* last reserved entry's index + 1 */ |
|---|
| 201 | + int last_reserved; |
|---|
| 202 | +}; |
|---|
| 236 | 203 | |
|---|
| 237 | 204 | /* GPU virtualization */ |
|---|
| 238 | 205 | struct amdgpu_virt { |
|---|
| 239 | 206 | uint32_t caps; |
|---|
| 240 | 207 | struct amdgpu_bo *csa_obj; |
|---|
| 241 | | - uint64_t csa_vmid0_addr; |
|---|
| 208 | + void *csa_cpu_addr; |
|---|
| 242 | 209 | bool chained_ib_support; |
|---|
| 243 | 210 | uint32_t reg_val_offs; |
|---|
| 244 | 211 | struct amdgpu_irq_src ack_irq; |
|---|
| .. | .. |
|---|
| 246 | 213 | struct work_struct flr_work; |
|---|
| 247 | 214 | struct amdgpu_mm_table mm_table; |
|---|
| 248 | 215 | const struct amdgpu_virt_ops *ops; |
|---|
| 249 | | - struct amdgpu_vf_error_buffer vf_errors; |
|---|
| 216 | + struct amdgpu_vf_error_buffer vf_errors; |
|---|
| 250 | 217 | struct amdgpu_virt_fw_reserve fw_reserve; |
|---|
| 251 | 218 | uint32_t gim_feature; |
|---|
| 252 | | -}; |
|---|
| 219 | + uint32_t reg_access_mode; |
|---|
| 220 | + int req_init_data_ver; |
|---|
| 221 | + bool tdr_debug; |
|---|
| 222 | + struct amdgpu_virt_ras_err_handler_data *virt_eh_data; |
|---|
| 223 | + bool ras_init_done; |
|---|
| 253 | 224 | |
|---|
| 254 | | -#define AMDGPU_CSA_SIZE (8 * 1024) |
|---|
| 225 | + /* vf2pf message */ |
|---|
| 226 | + struct delayed_work vf2pf_work; |
|---|
| 227 | + uint32_t vf2pf_update_interval_ms; |
|---|
| 228 | +}; |
|---|
| 255 | 229 | |
|---|
| 256 | 230 | #define amdgpu_sriov_enabled(adev) \ |
|---|
| 257 | 231 | ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) |
|---|
| .. | .. |
|---|
| 265 | 239 | #define amdgpu_sriov_runtime(adev) \ |
|---|
| 266 | 240 | ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_RUNTIME) |
|---|
| 267 | 241 | |
|---|
| 242 | +#define amdgpu_sriov_fullaccess(adev) \ |
|---|
| 243 | +(amdgpu_sriov_vf((adev)) && !amdgpu_sriov_runtime((adev))) |
|---|
| 244 | + |
|---|
| 268 | 245 | #define amdgpu_passthrough(adev) \ |
|---|
| 269 | 246 | ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE) |
|---|
| 247 | + |
|---|
| 248 | +#define amdgpu_sriov_vf_mmio_access_protection(adev) \ |
|---|
| 249 | +((adev)->virt.caps & AMDGPU_VF_MMIO_ACCESS_PROTECT) |
|---|
| 270 | 250 | |
|---|
| 271 | 251 | static inline bool is_virtual_machine(void) |
|---|
| 272 | 252 | { |
|---|
| .. | .. |
|---|
| 277 | 257 | #endif |
|---|
| 278 | 258 | } |
|---|
| 279 | 259 | |
|---|
| 280 | | -struct amdgpu_vm; |
|---|
| 260 | +#define amdgpu_sriov_is_pp_one_vf(adev) \ |
|---|
| 261 | + ((adev)->virt.gim_feature & AMDGIM_FEATURE_PP_ONE_VF) |
|---|
| 262 | +#define amdgpu_sriov_is_debug(adev) \ |
|---|
| 263 | + ((!amdgpu_in_reset(adev)) && adev->virt.tdr_debug) |
|---|
| 264 | +#define amdgpu_sriov_is_normal(adev) \ |
|---|
| 265 | + ((!amdgpu_in_reset(adev)) && (!adev->virt.tdr_debug)) |
|---|
| 281 | 266 | |
|---|
| 282 | | -uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev); |
|---|
| 283 | 267 | bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev); |
|---|
| 284 | | -int amdgpu_allocate_static_csa(struct amdgpu_device *adev); |
|---|
| 285 | | -int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, |
|---|
| 286 | | - struct amdgpu_bo_va **bo_va); |
|---|
| 287 | | -void amdgpu_free_static_csa(struct amdgpu_device *adev); |
|---|
| 288 | 268 | void amdgpu_virt_init_setting(struct amdgpu_device *adev); |
|---|
| 289 | | -uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); |
|---|
| 290 | | -void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); |
|---|
| 269 | +void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev, |
|---|
| 270 | + uint32_t reg0, uint32_t rreg1, |
|---|
| 271 | + uint32_t ref, uint32_t mask); |
|---|
| 291 | 272 | int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init); |
|---|
| 292 | 273 | int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init); |
|---|
| 293 | 274 | int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); |
|---|
| 275 | +void amdgpu_virt_request_init_data(struct amdgpu_device *adev); |
|---|
| 294 | 276 | int amdgpu_virt_wait_reset(struct amdgpu_device *adev); |
|---|
| 295 | 277 | int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); |
|---|
| 296 | 278 | void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); |
|---|
| 297 | | -int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size, |
|---|
| 298 | | - unsigned int key, |
|---|
| 299 | | - unsigned int chksum); |
|---|
| 279 | +void amdgpu_virt_release_ras_err_handler_data(struct amdgpu_device *adev); |
|---|
| 300 | 280 | void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); |
|---|
| 281 | +void amdgpu_virt_exchange_data(struct amdgpu_device *adev); |
|---|
| 282 | +void amdgpu_virt_fini_data_exchange(struct amdgpu_device *adev); |
|---|
| 283 | +void amdgpu_detect_virtualization(struct amdgpu_device *adev); |
|---|
| 301 | 284 | |
|---|
| 285 | +bool amdgpu_virt_can_access_debugfs(struct amdgpu_device *adev); |
|---|
| 286 | +int amdgpu_virt_enable_access_debugfs(struct amdgpu_device *adev); |
|---|
| 287 | +void amdgpu_virt_disable_access_debugfs(struct amdgpu_device *adev); |
|---|
| 288 | + |
|---|
| 289 | +enum amdgpu_sriov_vf_mode amdgpu_virt_get_sriov_vf_mode(struct amdgpu_device *adev); |
|---|
| 302 | 290 | #endif |
|---|