1ceeb50edSMonk Liu /* 2ceeb50edSMonk Liu * Copyright 2016 Advanced Micro Devices, Inc. 3ceeb50edSMonk Liu * 4ceeb50edSMonk Liu * Permission is hereby granted, free of charge, to any person obtaining a 5ceeb50edSMonk Liu * copy of this software and associated documentation files (the "Software"), 6ceeb50edSMonk Liu * to deal in the Software without restriction, including without limitation 7ceeb50edSMonk Liu * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8ceeb50edSMonk Liu * and/or sell copies of the Software, and to permit persons to whom the 9ceeb50edSMonk Liu * Software is furnished to do so, subject to the following conditions: 10ceeb50edSMonk Liu * 11ceeb50edSMonk Liu * The above copyright notice and this permission notice shall be included in 12ceeb50edSMonk Liu * all copies or substantial portions of the Software. 13ceeb50edSMonk Liu * 14ceeb50edSMonk Liu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15ceeb50edSMonk Liu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16ceeb50edSMonk Liu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17ceeb50edSMonk Liu * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18ceeb50edSMonk Liu * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ceeb50edSMonk Liu * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20ceeb50edSMonk Liu * OTHER DEALINGS IN THE SOFTWARE. 21ceeb50edSMonk Liu * 22ceeb50edSMonk Liu * Author: Monk.liu@amd.com 23ceeb50edSMonk Liu */ 24ceeb50edSMonk Liu #ifndef AMDGPU_VIRT_H 25ceeb50edSMonk Liu #define AMDGPU_VIRT_H 26ceeb50edSMonk Liu 27ceeb50edSMonk Liu #define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS (1 << 0) /* vBIOS is sr-iov ready */ 28ceeb50edSMonk Liu #define AMDGPU_SRIOV_CAPS_ENABLE_IOV (1 << 1) /* sr-iov is enabled on this GPU */ 29ceeb50edSMonk Liu #define AMDGPU_SRIOV_CAPS_IS_VF (1 << 2) /* this GPU is a virtual function */ 30ceeb50edSMonk Liu #define AMDGPU_PASSTHROUGH_MODE (1 << 3) /* thw whole GPU is pass through for VM */ 315ec9f06eSXiangliang Yu #define AMDGPU_SRIOV_CAPS_RUNTIME (1 << 4) /* is out of full access mode */ 32bd7de27dSMonk Liu 33ecb2b9c6SXiangliang Yu struct amdgpu_mm_table { 34ecb2b9c6SXiangliang Yu struct amdgpu_bo *bo; 35ecb2b9c6SXiangliang Yu uint32_t *cpu_addr; 36ecb2b9c6SXiangliang Yu uint64_t gpu_addr; 37ecb2b9c6SXiangliang Yu }; 38ecb2b9c6SXiangliang Yu 39e23b74aaSAlex Deucher #define AMDGPU_VF_ERROR_ENTRY_SIZE 16 40e23b74aaSAlex Deucher 41e23b74aaSAlex Deucher /* struct error_entry - amdgpu VF error information. */ 42e23b74aaSAlex Deucher struct amdgpu_vf_error_buffer { 43e23b74aaSAlex Deucher struct mutex lock; 44e23b74aaSAlex Deucher int read_count; 45e23b74aaSAlex Deucher int write_count; 46e23b74aaSAlex Deucher uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE]; 47e23b74aaSAlex Deucher uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE]; 48e23b74aaSAlex Deucher uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE]; 49e23b74aaSAlex Deucher }; 50e23b74aaSAlex Deucher 511e9f1392SXiangliang Yu /** 521e9f1392SXiangliang Yu * struct amdgpu_virt_ops - amdgpu device virt operations 531e9f1392SXiangliang Yu */ 541e9f1392SXiangliang Yu struct amdgpu_virt_ops { 551e9f1392SXiangliang Yu int (*req_full_gpu)(struct amdgpu_device *adev, bool init); 561e9f1392SXiangliang Yu int (*rel_full_gpu)(struct amdgpu_device *adev, bool init); 571e9f1392SXiangliang Yu int (*reset_gpu)(struct amdgpu_device *adev); 5889041940SGavin Wan void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3); 591e9f1392SXiangliang Yu }; 601e9f1392SXiangliang Yu 612dc8f81eSHorace Chen /* 622dc8f81eSHorace Chen * Firmware Reserve Frame buffer 632dc8f81eSHorace Chen */ 642dc8f81eSHorace Chen struct amdgpu_virt_fw_reserve { 652dc8f81eSHorace Chen struct amdgim_pf2vf_info_header *p_pf2vf; 662dc8f81eSHorace Chen struct amdgim_vf2pf_info_header *p_vf2pf; 672dc8f81eSHorace Chen unsigned int checksum_key; 682dc8f81eSHorace Chen }; 692dc8f81eSHorace Chen /* 702dc8f81eSHorace Chen * Defination between PF and VF 712dc8f81eSHorace Chen * Structures forcibly aligned to 4 to keep the same style as PF. 722dc8f81eSHorace Chen */ 732dc8f81eSHorace Chen #define AMDGIM_DATAEXCHANGE_OFFSET (64 * 1024) 742dc8f81eSHorace Chen 752dc8f81eSHorace Chen #define AMDGIM_GET_STRUCTURE_RESERVED_SIZE(total, u8, u16, u32, u64) \ 762dc8f81eSHorace Chen (total - (((u8)+3) / 4 + ((u16)+1) / 2 + (u32) + (u64)*2)) 772dc8f81eSHorace Chen 782dc8f81eSHorace Chen enum AMDGIM_FEATURE_FLAG { 792dc8f81eSHorace Chen /* GIM supports feature of Error log collecting */ 802dc8f81eSHorace Chen AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1, 812dc8f81eSHorace Chen /* GIM supports feature of loading uCodes */ 822dc8f81eSHorace Chen AMDGIM_FEATURE_GIM_LOAD_UCODES = 0x2, 832dc8f81eSHorace Chen }; 842dc8f81eSHorace Chen 852dc8f81eSHorace Chen struct amdgim_pf2vf_info_header { 862dc8f81eSHorace Chen /* the total structure size in byte. */ 872dc8f81eSHorace Chen uint32_t size; 882dc8f81eSHorace Chen /* version of this structure, written by the GIM */ 892dc8f81eSHorace Chen uint32_t version; 902dc8f81eSHorace Chen } __aligned(4); 912dc8f81eSHorace Chen struct amdgim_pf2vf_info_v1 { 922dc8f81eSHorace Chen /* header contains size and version */ 932dc8f81eSHorace Chen struct amdgim_pf2vf_info_header header; 942dc8f81eSHorace Chen /* max_width * max_height */ 952dc8f81eSHorace Chen unsigned int uvd_enc_max_pixels_count; 962dc8f81eSHorace Chen /* 16x16 pixels/sec, codec independent */ 972dc8f81eSHorace Chen unsigned int uvd_enc_max_bandwidth; 982dc8f81eSHorace Chen /* max_width * max_height */ 992dc8f81eSHorace Chen unsigned int vce_enc_max_pixels_count; 1002dc8f81eSHorace Chen /* 16x16 pixels/sec, codec independent */ 1012dc8f81eSHorace Chen unsigned int vce_enc_max_bandwidth; 1022dc8f81eSHorace Chen /* MEC FW position in kb from the start of visible frame buffer */ 1032dc8f81eSHorace Chen unsigned int mecfw_kboffset; 1042dc8f81eSHorace Chen /* The features flags of the GIM driver supports. */ 1052dc8f81eSHorace Chen unsigned int feature_flags; 1062dc8f81eSHorace Chen /* use private key from mailbox 2 to create chueksum */ 1072dc8f81eSHorace Chen unsigned int checksum; 1082dc8f81eSHorace Chen } __aligned(4); 1092dc8f81eSHorace Chen 1102dc8f81eSHorace Chen struct amdgim_pf2vf_info_v2 { 1112dc8f81eSHorace Chen /* header contains size and version */ 1122dc8f81eSHorace Chen struct amdgim_pf2vf_info_header header; 1132dc8f81eSHorace Chen /* use private key from mailbox 2 to create chueksum */ 1142dc8f81eSHorace Chen uint32_t checksum; 1152dc8f81eSHorace Chen /* The features flags of the GIM driver supports. */ 1162dc8f81eSHorace Chen uint32_t feature_flags; 1172dc8f81eSHorace Chen /* max_width * max_height */ 1182dc8f81eSHorace Chen uint32_t uvd_enc_max_pixels_count; 1192dc8f81eSHorace Chen /* 16x16 pixels/sec, codec independent */ 1202dc8f81eSHorace Chen uint32_t uvd_enc_max_bandwidth; 1212dc8f81eSHorace Chen /* max_width * max_height */ 1222dc8f81eSHorace Chen uint32_t vce_enc_max_pixels_count; 1232dc8f81eSHorace Chen /* 16x16 pixels/sec, codec independent */ 1242dc8f81eSHorace Chen uint32_t vce_enc_max_bandwidth; 1252dc8f81eSHorace Chen /* MEC FW position in kb from the start of VF visible frame buffer */ 1262dc8f81eSHorace Chen uint64_t mecfw_kboffset; 1272dc8f81eSHorace Chen /* MEC FW size in KB */ 1282dc8f81eSHorace Chen uint32_t mecfw_ksize; 1292dc8f81eSHorace Chen /* UVD FW position in kb from the start of VF visible frame buffer */ 1302dc8f81eSHorace Chen uint64_t uvdfw_kboffset; 1312dc8f81eSHorace Chen /* UVD FW size in KB */ 1322dc8f81eSHorace Chen uint32_t uvdfw_ksize; 1332dc8f81eSHorace Chen /* VCE FW position in kb from the start of VF visible frame buffer */ 1342dc8f81eSHorace Chen uint64_t vcefw_kboffset; 1352dc8f81eSHorace Chen /* VCE FW size in KB */ 1362dc8f81eSHorace Chen uint32_t vcefw_ksize; 1372dc8f81eSHorace Chen uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amdgim_pf2vf_info_header)/sizeof(uint32_t)), 3)]; 1382dc8f81eSHorace Chen } __aligned(4); 1392dc8f81eSHorace Chen 1402dc8f81eSHorace Chen 1412dc8f81eSHorace Chen struct amdgim_vf2pf_info_header { 1422dc8f81eSHorace Chen /* the total structure size in byte. */ 1432dc8f81eSHorace Chen uint32_t size; 1442dc8f81eSHorace Chen /*version of this structure, written by the guest */ 1452dc8f81eSHorace Chen uint32_t version; 1462dc8f81eSHorace Chen } __aligned(4); 1472dc8f81eSHorace Chen 1482dc8f81eSHorace Chen struct amdgim_vf2pf_info_v1 { 1492dc8f81eSHorace Chen /* header contains size and version */ 1502dc8f81eSHorace Chen struct amdgim_vf2pf_info_header header; 1512dc8f81eSHorace Chen /* driver version */ 1522dc8f81eSHorace Chen char driver_version[64]; 1532dc8f81eSHorace Chen /* driver certification, 1=WHQL, 0=None */ 1542dc8f81eSHorace Chen unsigned int driver_cert; 1552dc8f81eSHorace Chen /* guest OS type and version: need a define */ 1562dc8f81eSHorace Chen unsigned int os_info; 1572dc8f81eSHorace Chen /* in the unit of 1M */ 1582dc8f81eSHorace Chen unsigned int fb_usage; 1592dc8f81eSHorace Chen /* guest gfx engine usage percentage */ 1602dc8f81eSHorace Chen unsigned int gfx_usage; 1612dc8f81eSHorace Chen /* guest gfx engine health percentage */ 1622dc8f81eSHorace Chen unsigned int gfx_health; 1632dc8f81eSHorace Chen /* guest compute engine usage percentage */ 1642dc8f81eSHorace Chen unsigned int compute_usage; 1652dc8f81eSHorace Chen /* guest compute engine health percentage */ 1662dc8f81eSHorace Chen unsigned int compute_health; 1672dc8f81eSHorace Chen /* guest vce engine usage percentage. 0xffff means N/A. */ 1682dc8f81eSHorace Chen unsigned int vce_enc_usage; 1692dc8f81eSHorace Chen /* guest vce engine health percentage. 0xffff means N/A. */ 1702dc8f81eSHorace Chen unsigned int vce_enc_health; 1712dc8f81eSHorace Chen /* guest uvd engine usage percentage. 0xffff means N/A. */ 1722dc8f81eSHorace Chen unsigned int uvd_enc_usage; 1732dc8f81eSHorace Chen /* guest uvd engine usage percentage. 0xffff means N/A. */ 1742dc8f81eSHorace Chen unsigned int uvd_enc_health; 1752dc8f81eSHorace Chen unsigned int checksum; 1762dc8f81eSHorace Chen } __aligned(4); 1772dc8f81eSHorace Chen 1782dc8f81eSHorace Chen struct amdgim_vf2pf_info_v2 { 1792dc8f81eSHorace Chen /* header contains size and version */ 1802dc8f81eSHorace Chen struct amdgim_vf2pf_info_header header; 1812dc8f81eSHorace Chen uint32_t checksum; 1822dc8f81eSHorace Chen /* driver version */ 1832dc8f81eSHorace Chen uint8_t driver_version[64]; 1842dc8f81eSHorace Chen /* driver certification, 1=WHQL, 0=None */ 1852dc8f81eSHorace Chen uint32_t driver_cert; 1862dc8f81eSHorace Chen /* guest OS type and version: need a define */ 1872dc8f81eSHorace Chen uint32_t os_info; 1882dc8f81eSHorace Chen /* in the unit of 1M */ 1892dc8f81eSHorace Chen uint32_t fb_usage; 1902dc8f81eSHorace Chen /* guest gfx engine usage percentage */ 1912dc8f81eSHorace Chen uint32_t gfx_usage; 1922dc8f81eSHorace Chen /* guest gfx engine health percentage */ 1932dc8f81eSHorace Chen uint32_t gfx_health; 1942dc8f81eSHorace Chen /* guest compute engine usage percentage */ 1952dc8f81eSHorace Chen uint32_t compute_usage; 1962dc8f81eSHorace Chen /* guest compute engine health percentage */ 1972dc8f81eSHorace Chen uint32_t compute_health; 1982dc8f81eSHorace Chen /* guest vce engine usage percentage. 0xffff means N/A. */ 1992dc8f81eSHorace Chen uint32_t vce_enc_usage; 2002dc8f81eSHorace Chen /* guest vce engine health percentage. 0xffff means N/A. */ 2012dc8f81eSHorace Chen uint32_t vce_enc_health; 2022dc8f81eSHorace Chen /* guest uvd engine usage percentage. 0xffff means N/A. */ 2032dc8f81eSHorace Chen uint32_t uvd_enc_usage; 2042dc8f81eSHorace Chen /* guest uvd engine usage percentage. 0xffff means N/A. */ 2052dc8f81eSHorace Chen uint32_t uvd_enc_health; 2062dc8f81eSHorace Chen uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amdgim_vf2pf_info_header)/sizeof(uint32_t)), 0)]; 2072dc8f81eSHorace Chen } __aligned(4); 2082dc8f81eSHorace Chen 2092dc8f81eSHorace Chen #define AMDGPU_FW_VRAM_VF2PF_VER 2 2102dc8f81eSHorace Chen typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ; 2112dc8f81eSHorace Chen 2122dc8f81eSHorace Chen #define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \ 2132dc8f81eSHorace Chen do { \ 2142dc8f81eSHorace Chen ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \ 2152dc8f81eSHorace Chen } while (0) 2162dc8f81eSHorace Chen 2172dc8f81eSHorace Chen #define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \ 2182dc8f81eSHorace Chen do { \ 2192dc8f81eSHorace Chen (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \ 2202dc8f81eSHorace Chen } while (0) 2212dc8f81eSHorace Chen 2222dc8f81eSHorace Chen #define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \ 2232dc8f81eSHorace Chen do { \ 2242dc8f81eSHorace Chen if (!adev->virt.fw_reserve.p_pf2vf) \ 2252dc8f81eSHorace Chen *(val) = 0; \ 2262dc8f81eSHorace Chen else { \ 2272dc8f81eSHorace Chen if (adev->virt.fw_reserve.p_pf2vf->version == 1) \ 2282dc8f81eSHorace Chen *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \ 2292dc8f81eSHorace Chen if (adev->virt.fw_reserve.p_pf2vf->version == 2) \ 2302dc8f81eSHorace Chen *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \ 2312dc8f81eSHorace Chen } \ 2322dc8f81eSHorace Chen } while (0) 2332dc8f81eSHorace Chen 234ceeb50edSMonk Liu /* GPU virtualization */ 2355a5099cbSXiangliang Yu struct amdgpu_virt { 2365a5099cbSXiangliang Yu uint32_t caps; 237bd7de27dSMonk Liu struct amdgpu_bo *csa_obj; 238bd7de27dSMonk Liu uint64_t csa_vmid0_addr; 239ae65a26dSMonk Liu bool chained_ib_support; 240880e87e3SXiangliang Yu uint32_t reg_val_offs; 241147b5983SMonk Liu struct mutex lock_reset; 242ab71ac56SXiangliang Yu struct amdgpu_irq_src ack_irq; 243ab71ac56SXiangliang Yu struct amdgpu_irq_src rcv_irq; 244480da262SMonk Liu struct work_struct flr_work; 245ecb2b9c6SXiangliang Yu struct amdgpu_mm_table mm_table; 2461e9f1392SXiangliang Yu const struct amdgpu_virt_ops *ops; 247e23b74aaSAlex Deucher struct amdgpu_vf_error_buffer vf_errors; 2482dc8f81eSHorace Chen struct amdgpu_virt_fw_reserve fw_reserve; 249ceeb50edSMonk Liu }; 250ceeb50edSMonk Liu 251bd7de27dSMonk Liu #define AMDGPU_CSA_SIZE (8 * 1024) 252bd7de27dSMonk Liu #define AMDGPU_CSA_VADDR (AMDGPU_VA_RESERVED_SIZE - AMDGPU_CSA_SIZE) 253bd7de27dSMonk Liu 254ceeb50edSMonk Liu #define amdgpu_sriov_enabled(adev) \ 2555a5099cbSXiangliang Yu ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV) 256ceeb50edSMonk Liu 257ceeb50edSMonk Liu #define amdgpu_sriov_vf(adev) \ 2585a5099cbSXiangliang Yu ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_IS_VF) 259ceeb50edSMonk Liu 260ceeb50edSMonk Liu #define amdgpu_sriov_bios(adev) \ 2615a5099cbSXiangliang Yu ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS) 262ceeb50edSMonk Liu 2635ec9f06eSXiangliang Yu #define amdgpu_sriov_runtime(adev) \ 2645ec9f06eSXiangliang Yu ((adev)->virt.caps & AMDGPU_SRIOV_CAPS_RUNTIME) 2655ec9f06eSXiangliang Yu 266ceeb50edSMonk Liu #define amdgpu_passthrough(adev) \ 2675a5099cbSXiangliang Yu ((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE) 268ceeb50edSMonk Liu 269ceeb50edSMonk Liu static inline bool is_virtual_machine(void) 270ceeb50edSMonk Liu { 271ceeb50edSMonk Liu #ifdef CONFIG_X86 272ceeb50edSMonk Liu return boot_cpu_has(X86_FEATURE_HYPERVISOR); 273ceeb50edSMonk Liu #else 274ceeb50edSMonk Liu return false; 275ceeb50edSMonk Liu #endif 276ceeb50edSMonk Liu } 277ceeb50edSMonk Liu 2784e4bbe73SMonk Liu struct amdgpu_vm; 279a16f8f11Spding bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev); 2804e4bbe73SMonk Liu int amdgpu_allocate_static_csa(struct amdgpu_device *adev); 2810f4b3c68SChristian König int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm, 2820f4b3c68SChristian König struct amdgpu_bo_va **bo_va); 283bc992ba5SXiangliang Yu void amdgpu_virt_init_setting(struct amdgpu_device *adev); 284bc992ba5SXiangliang Yu uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg); 285bc992ba5SXiangliang Yu void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v); 2861e9f1392SXiangliang Yu int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init); 2871e9f1392SXiangliang Yu int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init); 2881e9f1392SXiangliang Yu int amdgpu_virt_reset_gpu(struct amdgpu_device *adev); 2897225f873SMonk Liu int amdgpu_sriov_gpu_reset(struct amdgpu_device *adev, struct amdgpu_job *job); 290904cd389SXiangliang Yu int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev); 291904cd389SXiangliang Yu void amdgpu_virt_free_mm_table(struct amdgpu_device *adev); 2922dc8f81eSHorace Chen int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size, 2932dc8f81eSHorace Chen unsigned int key, 2942dc8f81eSHorace Chen unsigned int chksum); 2952dc8f81eSHorace Chen void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev); 2964e4bbe73SMonk Liu 297ceeb50edSMonk Liu #endif 298