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 amd_sriov_msg_pf2vf_info_header *p_pf2vf;
  67        struct amd_sriov_msg_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        /* PP ONE VF MODE in GIM */
  87        AMDGIM_FEATURE_PP_ONE_VF = (1 << 4),
  88};
  89
  90struct amd_sriov_msg_pf2vf_info_header {
  91        /* the total structure size in byte. */
  92        uint32_t size;
  93        /* version of this structure, written by the GIM */
  94        uint32_t version;
  95        /* reserved */
  96        uint32_t reserved[2];
  97} __aligned(4);
  98struct  amdgim_pf2vf_info_v1 {
  99        /* header contains size and version */
 100        struct amd_sriov_msg_pf2vf_info_header header;
 101        /* max_width * max_height */
 102        unsigned int uvd_enc_max_pixels_count;
 103        /* 16x16 pixels/sec, codec independent */
 104        unsigned int uvd_enc_max_bandwidth;
 105        /* max_width * max_height */
 106        unsigned int vce_enc_max_pixels_count;
 107        /* 16x16 pixels/sec, codec independent */
 108        unsigned int vce_enc_max_bandwidth;
 109        /* MEC FW position in kb from the start of visible frame buffer */
 110        unsigned int mecfw_kboffset;
 111        /* The features flags of the GIM driver supports. */
 112        unsigned int feature_flags;
 113        /* use private key from mailbox 2 to create chueksum */
 114        unsigned int checksum;
 115} __aligned(4);
 116
 117struct  amdgim_pf2vf_info_v2 {
 118        /* header contains size and version */
 119        struct amd_sriov_msg_pf2vf_info_header header;
 120        /* use private key from mailbox 2 to create chueksum */
 121        uint32_t checksum;
 122        /* The features flags of the GIM driver supports. */
 123        uint32_t feature_flags;
 124        /* max_width * max_height */
 125        uint32_t uvd_enc_max_pixels_count;
 126        /* 16x16 pixels/sec, codec independent */
 127        uint32_t uvd_enc_max_bandwidth;
 128        /* max_width * max_height */
 129        uint32_t vce_enc_max_pixels_count;
 130        /* 16x16 pixels/sec, codec independent */
 131        uint32_t vce_enc_max_bandwidth;
 132        /* MEC FW position in kb from the start of VF visible frame buffer */
 133        uint64_t mecfw_kboffset;
 134        /* MEC FW size in KB */
 135        uint32_t mecfw_ksize;
 136        /* UVD FW position in kb from the start of VF visible frame buffer */
 137        uint64_t uvdfw_kboffset;
 138        /* UVD FW size in KB */
 139        uint32_t uvdfw_ksize;
 140        /* VCE FW position in kb from the start of VF visible frame buffer */
 141        uint64_t vcefw_kboffset;
 142        /* VCE FW size in KB */
 143        uint32_t vcefw_ksize;
 144        uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 0, 0, (9 + sizeof(struct amd_sriov_msg_pf2vf_info_header)/sizeof(uint32_t)), 3)];
 145} __aligned(4);
 146
 147
 148struct amd_sriov_msg_vf2pf_info_header {
 149        /* the total structure size in byte. */
 150        uint32_t size;
 151        /*version of this structure, written by the guest */
 152        uint32_t version;
 153        /* reserved */
 154        uint32_t reserved[2];
 155} __aligned(4);
 156
 157struct amdgim_vf2pf_info_v1 {
 158        /* header contains size and version */
 159        struct amd_sriov_msg_vf2pf_info_header header;
 160        /* driver version */
 161        char driver_version[64];
 162        /* driver certification, 1=WHQL, 0=None */
 163        unsigned int driver_cert;
 164        /* guest OS type and version: need a define */
 165        unsigned int os_info;
 166        /* in the unit of 1M */
 167        unsigned int fb_usage;
 168        /* guest gfx engine usage percentage */
 169        unsigned int gfx_usage;
 170        /* guest gfx engine health percentage */
 171        unsigned int gfx_health;
 172        /* guest compute engine usage percentage */
 173        unsigned int compute_usage;
 174        /* guest compute engine health percentage */
 175        unsigned int compute_health;
 176        /* guest vce engine usage percentage. 0xffff means N/A. */
 177        unsigned int vce_enc_usage;
 178        /* guest vce engine health percentage. 0xffff means N/A. */
 179        unsigned int vce_enc_health;
 180        /* guest uvd engine usage percentage. 0xffff means N/A. */
 181        unsigned int uvd_enc_usage;
 182        /* guest uvd engine usage percentage. 0xffff means N/A. */
 183        unsigned int uvd_enc_health;
 184        unsigned int checksum;
 185} __aligned(4);
 186
 187struct amdgim_vf2pf_info_v2 {
 188        /* header contains size and version */
 189        struct amd_sriov_msg_vf2pf_info_header header;
 190        uint32_t checksum;
 191        /* driver version */
 192        uint8_t driver_version[64];
 193        /* driver certification, 1=WHQL, 0=None */
 194        uint32_t driver_cert;
 195        /* guest OS type and version: need a define */
 196        uint32_t os_info;
 197        /* in the unit of 1M */
 198        uint32_t fb_usage;
 199        /* guest gfx engine usage percentage */
 200        uint32_t gfx_usage;
 201        /* guest gfx engine health percentage */
 202        uint32_t gfx_health;
 203        /* guest compute engine usage percentage */
 204        uint32_t compute_usage;
 205        /* guest compute engine health percentage */
 206        uint32_t compute_health;
 207        /* guest vce engine usage percentage. 0xffff means N/A. */
 208        uint32_t vce_enc_usage;
 209        /* guest vce engine health percentage. 0xffff means N/A. */
 210        uint32_t vce_enc_health;
 211        /* guest uvd engine usage percentage. 0xffff means N/A. */
 212        uint32_t uvd_enc_usage;
 213        /* guest uvd engine usage percentage. 0xffff means N/A. */
 214        uint32_t uvd_enc_health;
 215        uint32_t reserved[AMDGIM_GET_STRUCTURE_RESERVED_SIZE(256, 64, 0, (12 + sizeof(struct amd_sriov_msg_vf2pf_info_header)/sizeof(uint32_t)), 0)];
 216} __aligned(4);
 217
 218#define AMDGPU_FW_VRAM_VF2PF_VER 2
 219typedef struct amdgim_vf2pf_info_v2 amdgim_vf2pf_info ;
 220
 221#define AMDGPU_FW_VRAM_VF2PF_WRITE(adev, field, val) \
 222        do { \
 223                ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field = (val); \
 224        } while (0)
 225
 226#define AMDGPU_FW_VRAM_VF2PF_READ(adev, field, val) \
 227        do { \
 228                (*val) = ((amdgim_vf2pf_info *)adev->virt.fw_reserve.p_vf2pf)->field; \
 229        } while (0)
 230
 231#define AMDGPU_FW_VRAM_PF2VF_READ(adev, field, val) \
 232        do { \
 233                if (!adev->virt.fw_reserve.p_pf2vf) \
 234                        *(val) = 0; \
 235                else { \
 236                        if (adev->virt.fw_reserve.p_pf2vf->version == 1) \
 237                                *(val) = ((struct amdgim_pf2vf_info_v1 *)adev->virt.fw_reserve.p_pf2vf)->field; \
 238                        if (adev->virt.fw_reserve.p_pf2vf->version == 2) \
 239                                *(val) = ((struct amdgim_pf2vf_info_v2 *)adev->virt.fw_reserve.p_pf2vf)->field; \
 240                } \
 241        } while (0)
 242
 243/* GPU virtualization */
 244struct amdgpu_virt {
 245        uint32_t                        caps;
 246        struct amdgpu_bo                *csa_obj;
 247        void                            *csa_cpu_addr;
 248        bool chained_ib_support;
 249        uint32_t                        reg_val_offs;
 250        struct amdgpu_irq_src           ack_irq;
 251        struct amdgpu_irq_src           rcv_irq;
 252        struct work_struct              flr_work;
 253        struct amdgpu_mm_table          mm_table;
 254        const struct amdgpu_virt_ops    *ops;
 255        struct amdgpu_vf_error_buffer   vf_errors;
 256        struct amdgpu_virt_fw_reserve   fw_reserve;
 257        uint32_t gim_feature;
 258        uint32_t reg_access_mode;
 259};
 260
 261#define amdgpu_sriov_enabled(adev) \
 262((adev)->virt.caps & AMDGPU_SRIOV_CAPS_ENABLE_IOV)
 263
 264#define amdgpu_sriov_vf(adev) \
 265((adev)->virt.caps & AMDGPU_SRIOV_CAPS_IS_VF)
 266
 267#define amdgpu_sriov_bios(adev) \
 268((adev)->virt.caps & AMDGPU_SRIOV_CAPS_SRIOV_VBIOS)
 269
 270#define amdgpu_sriov_runtime(adev) \
 271((adev)->virt.caps & AMDGPU_SRIOV_CAPS_RUNTIME)
 272
 273#define amdgpu_sriov_fullaccess(adev) \
 274(amdgpu_sriov_vf((adev)) && !amdgpu_sriov_runtime((adev)))
 275
 276#define amdgpu_passthrough(adev) \
 277((adev)->virt.caps & AMDGPU_PASSTHROUGH_MODE)
 278
 279static inline bool is_virtual_machine(void)
 280{
 281#ifdef CONFIG_X86
 282        return boot_cpu_has(X86_FEATURE_HYPERVISOR);
 283#else
 284        return false;
 285#endif
 286}
 287
 288#define amdgpu_sriov_is_pp_one_vf(adev) \
 289        ((adev)->virt.gim_feature & AMDGIM_FEATURE_PP_ONE_VF)
 290
 291bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 292void amdgpu_virt_init_setting(struct amdgpu_device *adev);
 293void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
 294                                        uint32_t reg0, uint32_t rreg1,
 295                                        uint32_t ref, uint32_t mask);
 296int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
 297int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
 298int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
 299int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
 300int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
 301void amdgpu_virt_free_mm_table(struct amdgpu_device *adev);
 302int amdgpu_virt_fw_reserve_get_checksum(void *obj, unsigned long obj_size,
 303                                        unsigned int key,
 304                                        unsigned int chksum);
 305void amdgpu_virt_init_data_exchange(struct amdgpu_device *adev);
 306#endif
 307