linux/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.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 */
  23
  24#ifndef __AMDGPU_VCN_H__
  25#define __AMDGPU_VCN_H__
  26
  27#define AMDGPU_VCN_STACK_SIZE           (128*1024)
  28#define AMDGPU_VCN_CONTEXT_SIZE         (512*1024)
  29
  30#define AMDGPU_VCN_FIRMWARE_OFFSET      256
  31#define AMDGPU_VCN_MAX_ENC_RINGS        3
  32
  33#define AMDGPU_MAX_VCN_INSTANCES        2
  34#define AMDGPU_MAX_VCN_ENC_RINGS  AMDGPU_VCN_MAX_ENC_RINGS * AMDGPU_MAX_VCN_INSTANCES
  35
  36#define AMDGPU_VCN_HARVEST_VCN0 (1 << 0)
  37#define AMDGPU_VCN_HARVEST_VCN1 (1 << 1)
  38
  39#define VCN_DEC_KMD_CMD                 0x80000000
  40#define VCN_DEC_CMD_FENCE               0x00000000
  41#define VCN_DEC_CMD_TRAP                0x00000001
  42#define VCN_DEC_CMD_WRITE_REG           0x00000004
  43#define VCN_DEC_CMD_REG_READ_COND_WAIT  0x00000006
  44#define VCN_DEC_CMD_PACKET_START        0x0000000a
  45#define VCN_DEC_CMD_PACKET_END          0x0000000b
  46
  47#define VCN_DEC_SW_CMD_NO_OP            0x00000000
  48#define VCN_DEC_SW_CMD_END              0x00000001
  49#define VCN_DEC_SW_CMD_IB               0x00000002
  50#define VCN_DEC_SW_CMD_FENCE            0x00000003
  51#define VCN_DEC_SW_CMD_TRAP             0x00000004
  52#define VCN_DEC_SW_CMD_IB_AUTO          0x00000005
  53#define VCN_DEC_SW_CMD_SEMAPHORE        0x00000006
  54#define VCN_DEC_SW_CMD_PREEMPT_FENCE    0x00000009
  55#define VCN_DEC_SW_CMD_REG_WRITE        0x0000000b
  56#define VCN_DEC_SW_CMD_REG_WAIT         0x0000000c
  57
  58#define VCN_ENC_CMD_NO_OP               0x00000000
  59#define VCN_ENC_CMD_END                 0x00000001
  60#define VCN_ENC_CMD_IB                  0x00000002
  61#define VCN_ENC_CMD_FENCE               0x00000003
  62#define VCN_ENC_CMD_TRAP                0x00000004
  63#define VCN_ENC_CMD_REG_WRITE           0x0000000b
  64#define VCN_ENC_CMD_REG_WAIT            0x0000000c
  65
  66#define VCN_VID_SOC_ADDRESS_2_0         0x1fa00
  67#define VCN1_VID_SOC_ADDRESS_3_0        0x48200
  68#define VCN_AON_SOC_ADDRESS_2_0         0x1f800
  69#define VCN1_AON_SOC_ADDRESS_3_0        0x48000
  70#define VCN_VID_IP_ADDRESS_2_0          0x0
  71#define VCN_AON_IP_ADDRESS_2_0          0x30000
  72
  73#define mmUVD_RBC_XX_IB_REG_CHECK                                       0x026b
  74#define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX                              1
  75#define mmUVD_REG_XX_MASK                                               0x026c
  76#define mmUVD_REG_XX_MASK_BASE_IDX                                      1
  77
  78/* 1 second timeout */
  79#define VCN_IDLE_TIMEOUT        msecs_to_jiffies(1000)
  80
  81#define RREG32_SOC15_DPG_MODE_1_0(ip, inst_idx, reg, mask, sram_sel)                    \
  82        ({      WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);                   \
  83                WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,                           \
  84                        UVD_DPG_LMA_CTL__MASK_EN_MASK |                                 \
  85                        ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
  86                        << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |                   \
  87                        (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));                \
  88                RREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA);                         \
  89        })
  90
  91#define WREG32_SOC15_DPG_MODE_1_0(ip, inst_idx, reg, value, mask, sram_sel)             \
  92        do {                                                                            \
  93                WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA, value);                  \
  94                WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);                   \
  95                WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,                           \
  96                        UVD_DPG_LMA_CTL__READ_WRITE_MASK |                              \
  97                        ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
  98                        << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |                   \
  99                        (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));                \
 100        } while (0)
 101
 102#define SOC15_DPG_MODE_OFFSET(ip, inst_idx, reg)                                                \
 103        ({                                                                                      \
 104                uint32_t internal_reg_offset, addr;                                             \
 105                bool video_range, video1_range, aon_range, aon1_range;                          \
 106                                                                                                \
 107                addr = (adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg);           \
 108                addr <<= 2;                                                                     \
 109                video_range = ((((0xFFFFF & addr) >= (VCN_VID_SOC_ADDRESS_2_0)) &&              \
 110                                ((0xFFFFF & addr) < ((VCN_VID_SOC_ADDRESS_2_0 + 0x2600)))));    \
 111                video1_range = ((((0xFFFFF & addr) >= (VCN1_VID_SOC_ADDRESS_3_0)) &&            \
 112                                ((0xFFFFF & addr) < ((VCN1_VID_SOC_ADDRESS_3_0 + 0x2600)))));   \
 113                aon_range   = ((((0xFFFFF & addr) >= (VCN_AON_SOC_ADDRESS_2_0)) &&              \
 114                                ((0xFFFFF & addr) < ((VCN_AON_SOC_ADDRESS_2_0 + 0x600)))));     \
 115                aon1_range   = ((((0xFFFFF & addr) >= (VCN1_AON_SOC_ADDRESS_3_0)) &&            \
 116                                ((0xFFFFF & addr) < ((VCN1_AON_SOC_ADDRESS_3_0 + 0x600)))));    \
 117                if (video_range)                                                                \
 118                        internal_reg_offset = ((0xFFFFF & addr) - (VCN_VID_SOC_ADDRESS_2_0) +   \
 119                                (VCN_VID_IP_ADDRESS_2_0));                                      \
 120                else if (aon_range)                                                             \
 121                        internal_reg_offset = ((0xFFFFF & addr) - (VCN_AON_SOC_ADDRESS_2_0) +   \
 122                                (VCN_AON_IP_ADDRESS_2_0));                                      \
 123                else if (video1_range)                                                          \
 124                        internal_reg_offset = ((0xFFFFF & addr) - (VCN1_VID_SOC_ADDRESS_3_0) +  \
 125                                (VCN_VID_IP_ADDRESS_2_0));                                      \
 126                else if (aon1_range)                                                            \
 127                        internal_reg_offset = ((0xFFFFF & addr) - (VCN1_AON_SOC_ADDRESS_3_0) +  \
 128                                (VCN_AON_IP_ADDRESS_2_0));                                      \
 129                else                                                                            \
 130                        internal_reg_offset = (0xFFFFF & addr);                                 \
 131                                                                                                \
 132                internal_reg_offset >>= 2;                                                      \
 133        })
 134
 135#define RREG32_SOC15_DPG_MODE(inst_idx, offset, mask_en)                                        \
 136        ({                                                                                      \
 137                WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL,                                  \
 138                        (0x0 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT |                            \
 139                        mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT |                            \
 140                        offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT));                    \
 141                RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA);                                \
 142        })
 143
 144#define WREG32_SOC15_DPG_MODE(inst_idx, offset, value, mask_en, indirect)                       \
 145        do {                                                                                    \
 146                if (!indirect) {                                                                \
 147                        WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA, value);                 \
 148                        WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL,                          \
 149                                (0x1 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT |                    \
 150                                 mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT |                   \
 151                                 offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT));           \
 152                } else {                                                                        \
 153                        *adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = offset;                \
 154                        *adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = value;                 \
 155                }                                                                               \
 156        } while (0)
 157
 158#define AMDGPU_VCN_FW_SHARED_FLAG_0_RB  (1 << 6)
 159#define AMDGPU_VCN_MULTI_QUEUE_FLAG     (1 << 8)
 160#define AMDGPU_VCN_SW_RING_FLAG         (1 << 9)
 161
 162#define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER        0x00000001
 163#define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER          0x00000001
 164
 165enum fw_queue_mode {
 166        FW_QUEUE_RING_RESET = 1,
 167        FW_QUEUE_DPG_HOLD_OFF = 2,
 168};
 169
 170enum engine_status_constants {
 171        UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0,
 172        UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON_2_0 = 0xAAAA0,
 173        UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0 = 0x2A2A8AA0,
 174        UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON = 0x00000002,
 175        UVD_STATUS__UVD_BUSY = 0x00000004,
 176        GB_ADDR_CONFIG_DEFAULT = 0x26010011,
 177        UVD_STATUS__IDLE = 0x2,
 178        UVD_STATUS__BUSY = 0x5,
 179        UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF = 0x1,
 180        UVD_STATUS__RBC_BUSY = 0x1,
 181        UVD_PGFSM_STATUS_UVDJ_PWR_ON = 0,
 182};
 183
 184enum internal_dpg_state {
 185        VCN_DPG_STATE__UNPAUSE = 0,
 186        VCN_DPG_STATE__PAUSE,
 187};
 188
 189struct dpg_pause_state {
 190        enum internal_dpg_state fw_based;
 191        enum internal_dpg_state jpeg;
 192};
 193
 194struct amdgpu_vcn_reg{
 195        unsigned        data0;
 196        unsigned        data1;
 197        unsigned        cmd;
 198        unsigned        nop;
 199        unsigned        context_id;
 200        unsigned        ib_vmid;
 201        unsigned        ib_bar_low;
 202        unsigned        ib_bar_high;
 203        unsigned        ib_size;
 204        unsigned        gp_scratch8;
 205        unsigned        scratch9;
 206};
 207
 208struct amdgpu_vcn_inst {
 209        struct amdgpu_bo        *vcpu_bo;
 210        void                    *cpu_addr;
 211        uint64_t                gpu_addr;
 212        void                    *saved_bo;
 213        struct amdgpu_ring      ring_dec;
 214        struct amdgpu_ring      ring_enc[AMDGPU_VCN_MAX_ENC_RINGS];
 215        atomic_t                sched_score;
 216        struct amdgpu_irq_src   irq;
 217        struct amdgpu_vcn_reg   external;
 218        struct amdgpu_bo        *dpg_sram_bo;
 219        struct dpg_pause_state  pause_state;
 220        void                    *dpg_sram_cpu_addr;
 221        uint64_t                dpg_sram_gpu_addr;
 222        uint32_t                *dpg_sram_curr_addr;
 223        atomic_t                dpg_enc_submission_cnt;
 224        void                    *fw_shared_cpu_addr;
 225        uint64_t                fw_shared_gpu_addr;
 226};
 227
 228struct amdgpu_vcn {
 229        unsigned                fw_version;
 230        struct delayed_work     idle_work;
 231        const struct firmware   *fw;    /* VCN firmware */
 232        unsigned                num_enc_rings;
 233        enum amd_powergating_state cur_state;
 234        bool                    indirect_sram;
 235
 236        uint8_t num_vcn_inst;
 237        struct amdgpu_vcn_inst   inst[AMDGPU_MAX_VCN_INSTANCES];
 238        struct amdgpu_vcn_reg    internal;
 239        struct mutex             vcn_pg_lock;
 240        struct mutex            vcn1_jpeg1_workaround;
 241        atomic_t                 total_submission_cnt;
 242
 243        unsigned        harvest_config;
 244        int (*pause_dpg_mode)(struct amdgpu_device *adev,
 245                int inst_idx, struct dpg_pause_state *new_state);
 246};
 247
 248struct amdgpu_fw_shared_rb_ptrs_struct {
 249        /* to WA DPG R/W ptr issues.*/
 250        uint32_t  rptr;
 251        uint32_t  wptr;
 252};
 253
 254struct amdgpu_fw_shared_multi_queue {
 255        uint8_t decode_queue_mode;
 256        uint8_t encode_generalpurpose_queue_mode;
 257        uint8_t encode_lowlatency_queue_mode;
 258        uint8_t encode_realtime_queue_mode;
 259        uint8_t padding[4];
 260};
 261
 262struct amdgpu_fw_shared_sw_ring {
 263        uint8_t is_enabled;
 264        uint8_t padding[3];
 265};
 266
 267struct amdgpu_fw_shared {
 268        uint32_t present_flag_0;
 269        uint8_t pad[44];
 270        struct amdgpu_fw_shared_rb_ptrs_struct rb;
 271        uint8_t pad1[1];
 272        struct amdgpu_fw_shared_multi_queue multi_queue;
 273        struct amdgpu_fw_shared_sw_ring sw_ring;
 274};
 275
 276struct amdgpu_vcn_decode_buffer {
 277        uint32_t valid_buf_flag;
 278        uint32_t msg_buffer_address_hi;
 279        uint32_t msg_buffer_address_lo;
 280        uint32_t pad[30];
 281};
 282
 283#define VCN_BLOCK_ENCODE_DISABLE_MASK 0x80
 284#define VCN_BLOCK_DECODE_DISABLE_MASK 0x40
 285#define VCN_BLOCK_QUEUE_DISABLE_MASK 0xC0
 286
 287enum vcn_ring_type {
 288        VCN_ENCODE_RING,
 289        VCN_DECODE_RING,
 290        VCN_UNIFIED_RING,
 291};
 292
 293int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
 294int amdgpu_vcn_sw_fini(struct amdgpu_device *adev);
 295int amdgpu_vcn_suspend(struct amdgpu_device *adev);
 296int amdgpu_vcn_resume(struct amdgpu_device *adev);
 297void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring);
 298void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring);
 299
 300bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev,
 301                                enum vcn_ring_type type, uint32_t vcn_instance);
 302
 303int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring);
 304int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout);
 305int amdgpu_vcn_dec_sw_ring_test_ring(struct amdgpu_ring *ring);
 306int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout);
 307
 308int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring);
 309int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout);
 310
 311#endif
 312