Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2016 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #ifndef __AMDGPU_VCN_H__
0025 #define __AMDGPU_VCN_H__
0026 
0027 #include "amdgpu_ras.h"
0028 
0029 #define AMDGPU_VCN_STACK_SIZE       (128*1024)
0030 #define AMDGPU_VCN_CONTEXT_SIZE     (512*1024)
0031 
0032 #define AMDGPU_VCN_FIRMWARE_OFFSET  256
0033 #define AMDGPU_VCN_MAX_ENC_RINGS    3
0034 
0035 #define AMDGPU_MAX_VCN_INSTANCES    2
0036 #define AMDGPU_MAX_VCN_ENC_RINGS  AMDGPU_VCN_MAX_ENC_RINGS * AMDGPU_MAX_VCN_INSTANCES
0037 
0038 #define AMDGPU_VCN_HARVEST_VCN0 (1 << 0)
0039 #define AMDGPU_VCN_HARVEST_VCN1 (1 << 1)
0040 
0041 #define VCN_DEC_KMD_CMD         0x80000000
0042 #define VCN_DEC_CMD_FENCE       0x00000000
0043 #define VCN_DEC_CMD_TRAP        0x00000001
0044 #define VCN_DEC_CMD_WRITE_REG       0x00000004
0045 #define VCN_DEC_CMD_REG_READ_COND_WAIT  0x00000006
0046 #define VCN_DEC_CMD_PACKET_START    0x0000000a
0047 #define VCN_DEC_CMD_PACKET_END      0x0000000b
0048 
0049 #define VCN_DEC_SW_CMD_NO_OP        0x00000000
0050 #define VCN_DEC_SW_CMD_END      0x00000001
0051 #define VCN_DEC_SW_CMD_IB       0x00000002
0052 #define VCN_DEC_SW_CMD_FENCE        0x00000003
0053 #define VCN_DEC_SW_CMD_TRAP     0x00000004
0054 #define VCN_DEC_SW_CMD_IB_AUTO      0x00000005
0055 #define VCN_DEC_SW_CMD_SEMAPHORE    0x00000006
0056 #define VCN_DEC_SW_CMD_PREEMPT_FENCE    0x00000009
0057 #define VCN_DEC_SW_CMD_REG_WRITE    0x0000000b
0058 #define VCN_DEC_SW_CMD_REG_WAIT     0x0000000c
0059 
0060 #define VCN_ENC_CMD_NO_OP       0x00000000
0061 #define VCN_ENC_CMD_END         0x00000001
0062 #define VCN_ENC_CMD_IB          0x00000002
0063 #define VCN_ENC_CMD_FENCE       0x00000003
0064 #define VCN_ENC_CMD_TRAP        0x00000004
0065 #define VCN_ENC_CMD_REG_WRITE       0x0000000b
0066 #define VCN_ENC_CMD_REG_WAIT        0x0000000c
0067 
0068 #define VCN_AON_SOC_ADDRESS_2_0     0x1f800
0069 #define VCN1_AON_SOC_ADDRESS_3_0    0x48000
0070 #define VCN_VID_IP_ADDRESS_2_0      0x0
0071 #define VCN_AON_IP_ADDRESS_2_0      0x30000
0072 
0073 #define mmUVD_RBC_XX_IB_REG_CHECK                   0x026b
0074 #define mmUVD_RBC_XX_IB_REG_CHECK_BASE_IDX              1
0075 #define mmUVD_REG_XX_MASK                       0x026c
0076 #define mmUVD_REG_XX_MASK_BASE_IDX                  1
0077 
0078 /* 1 second timeout */
0079 #define VCN_IDLE_TIMEOUT    msecs_to_jiffies(1000)
0080 
0081 #define RREG32_SOC15_DPG_MODE_1_0(ip, inst_idx, reg, mask, sram_sel)            \
0082     ({  WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);           \
0083         WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,               \
0084             UVD_DPG_LMA_CTL__MASK_EN_MASK |                 \
0085             ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
0086             << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |           \
0087             (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));        \
0088         RREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA);             \
0089     })
0090 
0091 #define WREG32_SOC15_DPG_MODE_1_0(ip, inst_idx, reg, value, mask, sram_sel)         \
0092     do {                                        \
0093         WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA, value);          \
0094         WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);           \
0095         WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,               \
0096             UVD_DPG_LMA_CTL__READ_WRITE_MASK |              \
0097             ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
0098             << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |           \
0099             (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));        \
0100     } while (0)
0101 
0102 #define SOC15_DPG_MODE_OFFSET(ip, inst_idx, reg)                        \
0103     ({                                          \
0104         uint32_t internal_reg_offset, addr;                     \
0105         bool video_range, video1_range, aon_range, aon1_range;              \
0106                                                 \
0107         addr = (adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg);       \
0108         addr <<= 2;                                     \
0109         video_range = ((((0xFFFFF & addr) >= (VCN_VID_SOC_ADDRESS_2_0)) &&      \
0110                 ((0xFFFFF & addr) < ((VCN_VID_SOC_ADDRESS_2_0 + 0x2600)))));    \
0111         video1_range = ((((0xFFFFF & addr) >= (VCN1_VID_SOC_ADDRESS_3_0)) &&        \
0112                 ((0xFFFFF & addr) < ((VCN1_VID_SOC_ADDRESS_3_0 + 0x2600)))));   \
0113         aon_range   = ((((0xFFFFF & addr) >= (VCN_AON_SOC_ADDRESS_2_0)) &&      \
0114                 ((0xFFFFF & addr) < ((VCN_AON_SOC_ADDRESS_2_0 + 0x600))))); \
0115         aon1_range   = ((((0xFFFFF & addr) >= (VCN1_AON_SOC_ADDRESS_3_0)) &&        \
0116                 ((0xFFFFF & addr) < ((VCN1_AON_SOC_ADDRESS_3_0 + 0x600)))));    \
0117         if (video_range)                                \
0118             internal_reg_offset = ((0xFFFFF & addr) - (VCN_VID_SOC_ADDRESS_2_0) +   \
0119                 (VCN_VID_IP_ADDRESS_2_0));                  \
0120         else if (aon_range)                             \
0121             internal_reg_offset = ((0xFFFFF & addr) - (VCN_AON_SOC_ADDRESS_2_0) +   \
0122                 (VCN_AON_IP_ADDRESS_2_0));                  \
0123         else if (video1_range)                              \
0124             internal_reg_offset = ((0xFFFFF & addr) - (VCN1_VID_SOC_ADDRESS_3_0) +  \
0125                 (VCN_VID_IP_ADDRESS_2_0));                  \
0126         else if (aon1_range)                                \
0127             internal_reg_offset = ((0xFFFFF & addr) - (VCN1_AON_SOC_ADDRESS_3_0) +  \
0128                 (VCN_AON_IP_ADDRESS_2_0));                  \
0129         else                                        \
0130             internal_reg_offset = (0xFFFFF & addr);                 \
0131                                                 \
0132         internal_reg_offset >>= 2;                          \
0133     })
0134 
0135 #define RREG32_SOC15_DPG_MODE(inst_idx, offset, mask_en)                    \
0136     ({                                          \
0137         WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL,                  \
0138             (0x0 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT |                \
0139             mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT |                \
0140             offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT));            \
0141         RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA);                \
0142     })
0143 
0144 #define WREG32_SOC15_DPG_MODE(inst_idx, offset, value, mask_en, indirect)           \
0145     do {                                            \
0146         if (!indirect) {                                \
0147             WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_DATA, value);         \
0148             WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL,              \
0149                 (0x1 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT |            \
0150                  mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT |           \
0151                  offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT));       \
0152         } else {                                    \
0153             *adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = offset;        \
0154             *adev->vcn.inst[inst_idx].dpg_sram_curr_addr++ = value;         \
0155         }                                       \
0156     } while (0)
0157 
0158 #define AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE (1 << 2)
0159 #define AMDGPU_VCN_FW_SHARED_FLAG_0_RB  (1 << 6)
0160 #define AMDGPU_VCN_MULTI_QUEUE_FLAG (1 << 8)
0161 #define AMDGPU_VCN_SW_RING_FLAG     (1 << 9)
0162 #define AMDGPU_VCN_FW_LOGGING_FLAG  (1 << 10)
0163 #define AMDGPU_VCN_SMU_VERSION_INFO_FLAG (1 << 11)
0164 
0165 #define AMDGPU_VCN_IB_FLAG_DECODE_BUFFER    0x00000001
0166 #define AMDGPU_VCN_CMD_FLAG_MSG_BUFFER      0x00000001
0167 
0168 #define VCN_CODEC_DISABLE_MASK_AV1  (1 << 0)
0169 #define VCN_CODEC_DISABLE_MASK_VP9  (1 << 1)
0170 #define VCN_CODEC_DISABLE_MASK_HEVC (1 << 2)
0171 #define VCN_CODEC_DISABLE_MASK_H264 (1 << 3)
0172 
0173 enum fw_queue_mode {
0174     FW_QUEUE_RING_RESET = 1,
0175     FW_QUEUE_DPG_HOLD_OFF = 2,
0176 };
0177 
0178 enum engine_status_constants {
0179     UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON = 0x2AAAA0,
0180     UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON_2_0 = 0xAAAA0,
0181     UVD_PGFSM_STATUS__UVDM_UVDU_UVDLM_PWR_ON_3_0 = 0x2A2A8AA0,
0182     UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON = 0x00000002,
0183     UVD_STATUS__UVD_BUSY = 0x00000004,
0184     GB_ADDR_CONFIG_DEFAULT = 0x26010011,
0185     UVD_STATUS__IDLE = 0x2,
0186     UVD_STATUS__BUSY = 0x5,
0187     UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF = 0x1,
0188     UVD_STATUS__RBC_BUSY = 0x1,
0189     UVD_PGFSM_STATUS_UVDJ_PWR_ON = 0,
0190 };
0191 
0192 enum internal_dpg_state {
0193     VCN_DPG_STATE__UNPAUSE = 0,
0194     VCN_DPG_STATE__PAUSE,
0195 };
0196 
0197 struct dpg_pause_state {
0198     enum internal_dpg_state fw_based;
0199     enum internal_dpg_state jpeg;
0200 };
0201 
0202 struct amdgpu_vcn_reg{
0203     unsigned    data0;
0204     unsigned    data1;
0205     unsigned    cmd;
0206     unsigned    nop;
0207     unsigned    context_id;
0208     unsigned    ib_vmid;
0209     unsigned    ib_bar_low;
0210     unsigned    ib_bar_high;
0211     unsigned    ib_size;
0212     unsigned    gp_scratch8;
0213     unsigned    scratch9;
0214 };
0215 
0216 struct amdgpu_vcn_fw_shared {
0217     void        *cpu_addr;
0218     uint64_t    gpu_addr;
0219     uint32_t    mem_size;
0220     uint32_t    log_offset;
0221 };
0222 
0223 struct amdgpu_vcn_inst {
0224     struct amdgpu_bo    *vcpu_bo;
0225     void            *cpu_addr;
0226     uint64_t        gpu_addr;
0227     void            *saved_bo;
0228     struct amdgpu_ring  ring_dec;
0229     struct amdgpu_ring  ring_enc[AMDGPU_VCN_MAX_ENC_RINGS];
0230     atomic_t        sched_score;
0231     struct amdgpu_irq_src   irq;
0232     struct amdgpu_vcn_reg   external;
0233     struct amdgpu_bo    *dpg_sram_bo;
0234     struct dpg_pause_state  pause_state;
0235     void            *dpg_sram_cpu_addr;
0236     uint64_t        dpg_sram_gpu_addr;
0237     uint32_t        *dpg_sram_curr_addr;
0238     atomic_t        dpg_enc_submission_cnt;
0239     struct amdgpu_vcn_fw_shared fw_shared;
0240 };
0241 
0242 struct amdgpu_vcn_ras {
0243     struct amdgpu_ras_block_object ras_block;
0244 };
0245 
0246 struct amdgpu_vcn {
0247     unsigned        fw_version;
0248     struct delayed_work idle_work;
0249     const struct firmware   *fw;    /* VCN firmware */
0250     unsigned        num_enc_rings;
0251     enum amd_powergating_state cur_state;
0252     bool            indirect_sram;
0253 
0254     uint8_t num_vcn_inst;
0255     struct amdgpu_vcn_inst   inst[AMDGPU_MAX_VCN_INSTANCES];
0256     uint8_t          vcn_config[AMDGPU_MAX_VCN_INSTANCES];
0257     uint32_t         vcn_codec_disable_mask[AMDGPU_MAX_VCN_INSTANCES];
0258     struct amdgpu_vcn_reg    internal;
0259     struct mutex         vcn_pg_lock;
0260     struct mutex        vcn1_jpeg1_workaround;
0261     atomic_t         total_submission_cnt;
0262 
0263     unsigned    harvest_config;
0264     int (*pause_dpg_mode)(struct amdgpu_device *adev,
0265         int inst_idx, struct dpg_pause_state *new_state);
0266 
0267     struct ras_common_if    *ras_if;
0268     struct amdgpu_vcn_ras   *ras;
0269 };
0270 
0271 struct amdgpu_fw_shared_rb_ptrs_struct {
0272     /* to WA DPG R/W ptr issues.*/
0273     uint32_t  rptr;
0274     uint32_t  wptr;
0275 };
0276 
0277 struct amdgpu_fw_shared_multi_queue {
0278     uint8_t decode_queue_mode;
0279     uint8_t encode_generalpurpose_queue_mode;
0280     uint8_t encode_lowlatency_queue_mode;
0281     uint8_t encode_realtime_queue_mode;
0282     uint8_t padding[4];
0283 };
0284 
0285 struct amdgpu_fw_shared_sw_ring {
0286     uint8_t is_enabled;
0287     uint8_t padding[3];
0288 };
0289 
0290 struct amdgpu_fw_shared_unified_queue_struct {
0291     uint8_t is_enabled;
0292     uint8_t queue_mode;
0293     uint8_t queue_status;
0294     uint8_t padding[5];
0295 };
0296 
0297 struct amdgpu_fw_shared_fw_logging {
0298     uint8_t is_enabled;
0299     uint32_t addr_lo;
0300     uint32_t addr_hi;
0301     uint32_t size;
0302 };
0303 
0304 struct amdgpu_fw_shared_smu_interface_info {
0305     uint8_t smu_interface_type;
0306     uint8_t padding[3];
0307 };
0308 
0309 struct amdgpu_fw_shared {
0310     uint32_t present_flag_0;
0311     uint8_t pad[44];
0312     struct amdgpu_fw_shared_rb_ptrs_struct rb;
0313     uint8_t pad1[1];
0314     struct amdgpu_fw_shared_multi_queue multi_queue;
0315     struct amdgpu_fw_shared_sw_ring sw_ring;
0316     struct amdgpu_fw_shared_fw_logging fw_log;
0317     struct amdgpu_fw_shared_smu_interface_info smu_interface_info;
0318 };
0319 
0320 struct amdgpu_vcn4_fw_shared {
0321     uint32_t present_flag_0;
0322     uint8_t pad[12];
0323     struct amdgpu_fw_shared_unified_queue_struct sq;
0324     uint8_t pad1[8];
0325     struct amdgpu_fw_shared_fw_logging fw_log;
0326 };
0327 
0328 struct amdgpu_vcn_fwlog {
0329     uint32_t rptr;
0330     uint32_t wptr;
0331     uint32_t buffer_size;
0332     uint32_t header_size;
0333     uint8_t wrapped;
0334 };
0335 
0336 struct amdgpu_vcn_decode_buffer {
0337     uint32_t valid_buf_flag;
0338     uint32_t msg_buffer_address_hi;
0339     uint32_t msg_buffer_address_lo;
0340     uint32_t pad[30];
0341 };
0342 
0343 #define VCN_BLOCK_ENCODE_DISABLE_MASK 0x80
0344 #define VCN_BLOCK_DECODE_DISABLE_MASK 0x40
0345 #define VCN_BLOCK_QUEUE_DISABLE_MASK 0xC0
0346 
0347 enum vcn_ring_type {
0348     VCN_ENCODE_RING,
0349     VCN_DECODE_RING,
0350     VCN_UNIFIED_RING,
0351 };
0352 
0353 int amdgpu_vcn_sw_init(struct amdgpu_device *adev);
0354 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev);
0355 int amdgpu_vcn_suspend(struct amdgpu_device *adev);
0356 int amdgpu_vcn_resume(struct amdgpu_device *adev);
0357 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring);
0358 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring);
0359 
0360 bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev,
0361                 enum vcn_ring_type type, uint32_t vcn_instance);
0362 
0363 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring);
0364 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout);
0365 int amdgpu_vcn_dec_sw_ring_test_ring(struct amdgpu_ring *ring);
0366 int amdgpu_vcn_dec_sw_ring_test_ib(struct amdgpu_ring *ring, long timeout);
0367 int amdgpu_vcn_unified_ring_test_ib(struct amdgpu_ring *ring, long timeout);
0368 
0369 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring);
0370 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout);
0371 
0372 enum amdgpu_ring_priority_level amdgpu_vcn_get_enc_ring_prio(int ring);
0373 
0374 void amdgpu_vcn_setup_ucode(struct amdgpu_device *adev);
0375 
0376 void amdgpu_vcn_fwlog_init(struct amdgpu_vcn_inst *vcn);
0377 void amdgpu_debugfs_vcn_fwlog_init(struct amdgpu_device *adev,
0378                                    uint8_t i, struct amdgpu_vcn_inst *vcn);
0379 
0380 int amdgpu_vcn_process_poison_irq(struct amdgpu_device *adev,
0381             struct amdgpu_irq_src *source,
0382             struct amdgpu_iv_entry *entry);
0383 
0384 #endif