linux/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
<<
>>
Prefs
   1/*
   2 * Copyright 2016 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 * Author: Monk.liu@amd.com
  23 */
  24#ifndef AMDGPU_VIRT_H
  25#define AMDGPU_VIRT_H
  26
  27#define AMDGPU_SRIOV_CAPS_SRIOV_VBIOS  (1 << 0) /* vBIOS is sr-iov ready */
  28#define AMDGPU_SRIOV_CAPS_ENABLE_IOV   (1 << 1) /* sr-iov is enabled on this GPU */
  29#define AMDGPU_SRIOV_CAPS_IS_VF        (1 << 2) /* this GPU is a virtual function */
  30#define AMDGPU_PASSTHROUGH_MODE        (1 << 3) /* thw whole GPU is pass through for VM */
  31#define AMDGPU_SRIOV_CAPS_RUNTIME      (1 << 4) /* is out of full access mode */
  32
  33struct amdgpu_mm_table {
  34        struct amdgpu_bo        *bo;
  35        uint32_t                *cpu_addr;
  36        uint64_t                gpu_addr;
  37};
  38
  39#define AMDGPU_VF_ERROR_ENTRY_SIZE    16
  40
  41/* struct error_entry - amdgpu VF error information. */
  42struct amdgpu_vf_error_buffer {
  43        struct mutex lock;
  44        int read_count;
  45        int write_count;
  46        uint16_t code[AMDGPU_VF_ERROR_ENTRY_SIZE];
  47        uint16_t flags[AMDGPU_VF_ERROR_ENTRY_SIZE];
  48        uint64_t data[AMDGPU_VF_ERROR_ENTRY_SIZE];
  49};
  50
  51/**
  52 * struct amdgpu_virt_ops - amdgpu device virt operations
  53 */
  54struct amdgpu_virt_ops {
  55        int (*req_full_gpu)(struct amdgpu_device *adev, bool init);
  56        int (*rel_full_gpu)(struct amdgpu_device *adev, bool init);
  57        int (*reset_gpu)(struct amdgpu_device *adev);
  58        int (*wait_reset)(struct amdgpu_device *adev);
  59        void (*trans_msg)(struct amdgpu_device *adev, u32 req, u32 data1, u32 data2, u32 data3);
  60};
  61
  62/*
  63 * Firmware Reserve Frame buffer
  64 */
  65struct amdgpu_virt_fw_reserve {
  66        struct amdgim_pf2vf_info_header *p_pf2vf;
  67        struct amdgim_vf2pf_info_header *p_vf2pf;
  68        unsigned int checksum_key;
  69};
  70/*
  71 * Defination between PF and VF
  72 * Structures forcibly aligned to 4 to keep the same style as PF.
  73 */
  74#define AMDGIM_DATAEXCHANGE_OFFSET              (64 * 1024)
  75
  76#define AMDGIM_GET_STRUCTURE_RESERVED_SIZE(total, u8, u16, u32, u64) \
  77                (total - (((u8)+3) / 4 + ((u16)+1) / 2 + (u32) + (u64)*2))
  78
  79enum AMDGIM_FEATURE_FLAG {
  80        /* GIM supports feature of Error log collecting */
  81        AMDGIM_FEATURE_ERROR_LOG_COLLECT = 0x1,
  82        /* GIM supports feature of loading uCodes */
  83        AMDGIM_FEATURE_GIM_LOAD_UCODES   = 0x2,
  84        /* VRAM LOST by GIM */
  85        AMDGIM_FEATURE_GIM_FLR_VRAMLOST = 0x4,
  86};
  87
  88struct 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);
  94struct  amdgim_pf2vf_info_v1 {
  95        /* header contains size and version */
  96        struct amdgim_pf2vf_info_header header;
  97        /* max_width * max_height */
  98        unsigned int uvd_enc_max_pixels_count;
  99        /* 16x16 pixels/sec, codec independent */
 100        unsigned int uvd_enc_max_bandwidth;
 101        /* max_width * max_height */
 102        unsigned int vce_enc_max_pixels_count;
 103        /* 16x16 pixels/sec, codec independent */
 104        unsigned int vce_enc_max_bandwidth;
 105        /* MEC FW position in kb from the start of visible frame buffer */
 106        unsigned int mecfw_kboffset;
 107        /* The features flags of the GIM driver supports. */
 108        unsigned int feature_flags;
 109        /* use private key from mailbox 2 to create chueksum */
 110        unsigned int checksum;
 111} __aligned(4);
 112
 113struct  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
 144struct 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
 151struct amdgim_vf2pf_info_v1 {
 152        /* header contains size and version */
 153        struct amdgim_vf2pf_info_header header;
 154        /* driver version */
 155        char driver_version[64];
 156        /* driver certification, 1=WHQL, 0=None */
 157        unsigned int driver_cert;
 158        /* guest OS type and version: need a define */
 159        unsigned int os_info;
 160        /* in the unit of 1M */
 161        unsigned int fb_usage;
 162        /* guest gfx engine usage percentage */
 163        unsigned int gfx_usage;
 164        /* guest gfx engine health percentage */
 165        unsigned int gfx_health;
 166        /* guest compute engine usage percentage */
 167        unsigned int compute_usage;
 168        /* guest compute engine health percentage */
 169        unsigned int compute_health;
 170        /* guest vce engine usage percentage. 0xffff means N/A. */
 171        unsigned int vce_enc_usage;
 172        /* guest vce engine health percentage. 0xffff means N/A. */
 173        unsigned int vce_enc_health;
 174        /* guest uvd engine usage percentage. 0xffff means N/A. */
 175        unsigned int uvd_enc_usage;
 176        /* guest uvd engine usage percentage. 0xffff means N/A. */
 177        unsigned int uvd_enc_health;
 178        unsigned int checksum;
 179} __aligned(4);
 180
 181struct amdgim_vf2pf_info_v2 {
 182        /* header contains size and version */
 183        struct amdgim_vf2pf_info_header header;
 184        uint32_t checksum;
 185        /* driver version */
 186        uint8_t driver_version[64];
 187        /* driver certification, 1=WHQL, 0=None */
 188        uint32_t driver_cert;
 189        /* guest OS type and version: need a define */
 190        uint32_t os_info;
 191        /* in the unit of 1M */
 192        uint32_t fb_usage;
 193        /* guest gfx engine usage percentage */
 194        uint32_t gfx_usage;
 195        /* guest gfx engine health percentage */
 196        uint32_t gfx_health;
 197        /* guest compute engine usage percentage */
 198        uint32_t compute_usage;
 199        /* guest compute engine health percentage */
 200        uint32_t compute_health;
 201        /* guest vce engine usage percentage. 0xffff means N/A. */
 202        uint32_t vce_enc_usage;
 203        /* guest vce engine health percentage. 0xffff means N/A. */
 204        uint32_t vce_enc_health;
 205        /* guest uvd engine usage percentage. 0xffff means N/A. */
 206        uint32_t uvd_enc_usage;
 207        /* guest uvd engine usage percentage. 0xffff means N/A. */
 208        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)];
 210} __aligned(4);
 211
 212#define AMDGPU_FW_VRAM_VF2PF_VER 2
 213typedef 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)
 236
 237/* GPU virtualization */
 238struct amdgpu_virt {
 239        uint32_t                        caps;
 240        struct amdgpu_bo                *csa_obj;
 241        uint64_t                        csa_vmid0_addr;
 242        bool chained_ib_support;
 243        uint32_t                        reg_val_offs;
 244        struct amdgpu_irq_src           ack_irq;
 245        struct amdgpu_irq_src           rcv_irq;
 246        struct work_struct              flr_work;
 247        struct amdgpu_mm_table          mm_table;
 248        const struct amdgpu_virt_ops    *ops;
 249        struct amdgpu_vf_error_buffer   vf_errors;
 250        struct amdgpu_virt_fw_reserve   fw_reserve;
 251        uint32_t gim_feature;
 252};
 253
 254#define AMDGPU_CSA_SIZE         (8 * 1024)
 255
 256#define amdgpu_sriov_enabled(adev) \
 257((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV)
 258
 259#define amdgpu_sriov_vf(adev) \
 260((adev)->virt.caps & AMDGPU_SRIOV_CAPS_IS_VF)
 261
 262#define amdgpu_sriov_bios(adev) \
 263((adev)->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)
 264
 265#define amdgpu_sriov_runtime(adev) \
 266((adev)->virt.caps & AMDGPU_SRIOV_CAPS_RUNTIME)
 267
 268#define amdgpu_passthrough(adev) \
 269((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
 270
 271static inline bool is_virtual_machine(void)
 272{
 273#ifdef CONFIG_X86
 274        return boot_cpu_has(X86_FEATURE_HYPERVISOR);
 275#else
 276        return false;
 277#endif
 278}
 279
 280struct amdgpu_vm;
 281
 282uint64_t amdgpu_csa_vaddr(struct amdgpu_device *adev);
 283bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 284int amdgpu_allocate_static_csa(struct amdgpu_device *adev);
 285int amdgpu_map_static_csa(struct amdgpu_device *adev, struct amdgpu_vm *vm,
 286                          struct amdgpu_bo_va **bo_va);
 287void amdgpu_free_static_csa(struct amdgpu_device *adev);
 288void amdgpu_virt_init_setting(struct amdgpu_device *adev);
 289uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
 290void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
 291int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
 292int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
 293int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
 294int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
 295int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
 296void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
 297int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
 298                                        unsigned int key,
 299                                        unsigned int chksum);
 300void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
 301
 302#endif
 303