Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/gpu/drm/amd/amdgpu/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 231 kB image not shown  

Quelle  gfx_v11_0.c   Sprache: C

 
/*
 * Copyright 2021 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "amdgpu.h"
#include "amdgpu_gfx.h"
#include "amdgpu_psp.h"
#include "amdgpu_smu.h"
#include "imu_v11_0.h"
#include "soc21.h"
#include "nvd.h"

#include "gc/gc_11_0_0_offset.h"
#include "gc/gc_11_0_0_sh_mask.h"
#include "smuio/smuio_13_0_6_offset.h"
#include "smuio/smuio_13_0_6_sh_mask.h"
#include "navi10_enum.h"
#include "ivsrcid/gfx/irqsrcs_gfx_11_0_0.h"

#include "soc15.h"
#include "clearstate_gfx11.h"
#include "v11_structs.h"
#include "gfx_v11_0.h"
#include "gfx_v11_0_cleaner_shader.h"
#include "gfx_v11_0_3.h"
#include "nbio_v4_3.h"
#include "mes_v11_0.h"
#include "mes_userqueue.h"
#include "amdgpu_userq_fence.h"

#define GFX11_NUM_GFX_RINGS  1
#define GFX11_MEC_HPD_SIZE 2048

#define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
#define RLC_PG_DELAY_3_DEFAULT_GC_11_0_1 0x1388

#define regCGTT_WD_CLK_CTRL  0x5086
#define regCGTT_WD_CLK_CTRL_BASE_IDX 1
#define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1 0x4e7e
#define regRLC_RLCS_BOOTLOAD_STATUS_gc_11_0_1_BASE_IDX 1
#define regPC_CONFIG_CNTL_1  0x194d
#define regPC_CONFIG_CNTL_1_BASE_IDX 1

#define regCP_GFX_MQD_CONTROL_DEFAULT                                             0x00000100
#define regCP_GFX_HQD_VMID_DEFAULT                                                0x00000000
#define regCP_GFX_HQD_QUEUE_PRIORITY_DEFAULT                                      0x00000000
#define regCP_GFX_HQD_QUANTUM_DEFAULT                                             0x00000a01
#define regCP_GFX_HQD_CNTL_DEFAULT                                                0x00a00000
#define regCP_RB_DOORBELL_CONTROL_DEFAULT                                         0x00000000
#define regCP_GFX_HQD_RPTR_DEFAULT                                                0x00000000

#define regCP_HQD_EOP_CONTROL_DEFAULT                                             0x00000006
#define regCP_HQD_PQ_DOORBELL_CONTROL_DEFAULT                                     0x00000000
#define regCP_MQD_CONTROL_DEFAULT                                                 0x00000100
#define regCP_HQD_PQ_CONTROL_DEFAULT                                              0x00308509
#define regCP_HQD_PQ_DOORBELL_CONTROL_DEFAULT                                     0x00000000
#define regCP_HQD_PQ_RPTR_DEFAULT                                                 0x00000000
#define regCP_HQD_PERSISTENT_STATE_DEFAULT                                        0x0be05501
#define regCP_HQD_IB_CONTROL_DEFAULT                                              0x00300000

MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc_kicker.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc_1.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_1_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_2_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_3_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_4_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_4_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_4_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_0_4_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_0_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_0_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_0_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_0_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_1_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_1_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_1_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_1_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_2_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_2_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_2_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_2_rlc.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_pfp.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_me.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_mec.bin");
MODULE_FIRMWARE("amdgpu/gc_11_5_3_rlc.bin");

static const struct amdgpu_hwip_reg_entry gc_reg_list_11_0[] = {
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS2),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS3),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_STALLED_STAT1),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_STALLED_STAT2),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_STALLED_STAT3),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPC_STALLED_STAT1),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPF_STALLED_STAT1),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_BUSY_STAT),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPC_BUSY_STAT),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPF_BUSY_STAT),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPC_BUSY_STAT2),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPF_BUSY_STAT2),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPF_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_ERROR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HPD_STATUS0),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_BASE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_WPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB0_BASE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB0_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB0_WPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB1_BASE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB1_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB1_WPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_CMD_BUFSZ),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB2_CMD_BUFSZ),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BASE_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BASE_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BUFSZ),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB2_BASE_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB2_BASE_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB2_BUFSZ),
 SOC15_REG_ENTRY_STR(GC, 0, regCPF_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regCPC_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regCPG_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regGDS_PROTECTION_FAULT),
 SOC15_REG_ENTRY_STR(GC, 0, regGDS_VM_PROTECTION_FAULT),
 SOC15_REG_ENTRY_STR(GC, 0, regIA_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regIA_UTCL1_STATUS_2),
 SOC15_REG_ENTRY_STR(GC, 0, regPA_CL_CNTL_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regRLC_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regRMI_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regSQC_CACHES),
 SOC15_REG_ENTRY_STR(GC, 0, regSQG_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regWD_UTCL1_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regGCVM_L2_PROTECTION_FAULT_CNTL),
 SOC15_REG_ENTRY_STR(GC, 0, regGCVM_L2_PROTECTION_FAULT_STATUS),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_DEBUG),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MEC_CNTL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_CNTL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MEC1_INSTR_PNTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_DEBUG_INTERRUPT_INSTR_PNTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_INSTR_PNTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_INSTR_PNTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_INSTR_PNTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_CPC_STATUS),
 /* cp header registers */
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_MES_HEADER_DUMP),
 /* SE status registers */
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE0),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE1),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE2),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE3),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE4),
 SOC15_REG_ENTRY_STR(GC, 0, regGRBM_STATUS_SE5)
};

static const struct amdgpu_hwip_reg_entry gc_cp_reg_list_11[] = {
 /* compute registers */
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_VMID),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PERSISTENT_STATE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PIPE_PRIORITY),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_QUEUE_PRIORITY),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_QUANTUM),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_BASE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_BASE_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_WPTR_POLL_ADDR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_WPTR_POLL_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_DOORBELL_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_IB_BASE_ADDR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_IB_BASE_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_IB_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_IB_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_DEQUEUE_REQUEST),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_BASE_ADDR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_BASE_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_WPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_EVENTS),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CTX_SAVE_BASE_ADDR_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CTX_SAVE_BASE_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CTX_SAVE_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CNTL_STACK_OFFSET),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CNTL_STACK_SIZE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_WG_STATE_OFFSET),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_CTX_SAVE_SIZE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_GDS_RESOURCE_STATE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_ERROR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_EOP_WPTR_MEM),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_WPTR_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_PQ_WPTR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_SUSPEND_CNTL_STACK_OFFSET),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_SUSPEND_CNTL_STACK_DW_CNT),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_SUSPEND_WG_STATE_OFFSET),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_HQD_DEQUEUE_STATUS),
 /* cp header registers */
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
};

static const struct amdgpu_hwip_reg_entry gc_gfx_queue_reg_list_11[] = {
 /* gfx queue registers */
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_ACTIVE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_VMID),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_QUEUE_PRIORITY),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_QUANTUM),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_BASE),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_BASE_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_OFFSET),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_CNTL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_CSMD_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_WPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_WPTR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_DEQUEUE_REQUEST),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_MAPPED),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_QUE_MGR_CONTROL),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_HQ_CONTROL0),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_HQD_HQ_STATUS0),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_MQD_BASE_ADDR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_GFX_MQD_BASE_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_WPTR_POLL_ADDR_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_WPTR_POLL_ADDR_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_RB_RPTR),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BASE_LO),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BASE_HI),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_CMD_BUFSZ),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_IB1_BUFSZ),
 /* cp header registers */
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_PFP_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
 SOC15_REG_ENTRY_STR(GC, 0, regCP_ME_HEADER_DUMP),
};

static const struct soc15_reg_golden golden_settings_gc_11_0[] = {
 SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL, 0x20000000, 0x20000000)
};

static const struct soc15_reg_golden golden_settings_gc_11_0_1[] =
{
 SOC15_REG_GOLDEN_VALUE(GC, 0, regCGTT_GS_NGG_CLK_CTRL, 0x9fff8fff, 0x00000010),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regCGTT_WD_CLK_CTRL, 0xffff8fff, 0x00000010),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regCPF_GCR_CNTL, 0x0007ffff, 0x0000c200),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regGL2C_CTRL3, 0xffff001b, 0x00f01988),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_CL_ENHANCE, 0xf0ffffff, 0x00880007),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_SC_ENHANCE_3, 0xfffffffd, 0x00000008),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regPA_SC_VRS_SURFACE_CNTL_1, 0xfff891ff, 0x55480100),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regTA_CNTL_AUX, 0xf7f7ffff, 0x01030000),
 SOC15_REG_GOLDEN_VALUE(GC, 0, regTCP_CNTL2, 0xfcffffff, 0x0000000a)
};

#define DEFAULT_SH_MEM_CONFIG \
 ((SH_MEM_ADDRESS_MODE_64 << SH_MEM_CONFIG__ADDRESS_MODE__SHIFT) | \
  (SH_MEM_ALIGNMENT_MODE_UNALIGNED << SH_MEM_CONFIG__ALIGNMENT_MODE__SHIFT) | \
  (3 << SH_MEM_CONFIG__INITIAL_INST_PREFETCH__SHIFT))

static void gfx_v11_0_disable_gpa_mode(struct amdgpu_device *adev);
static void gfx_v11_0_set_ring_funcs(struct amdgpu_device *adev);
static void gfx_v11_0_set_irq_funcs(struct amdgpu_device *adev);
static void gfx_v11_0_set_gds_init(struct amdgpu_device *adev);
static void gfx_v11_0_set_rlc_funcs(struct amdgpu_device *adev);
static void gfx_v11_0_set_mqd_funcs(struct amdgpu_device *adev);
static void gfx_v11_0_set_imu_funcs(struct amdgpu_device *adev);
static int gfx_v11_0_get_cu_info(struct amdgpu_device *adev,
                                 struct amdgpu_cu_info *cu_info);
static uint64_t gfx_v11_0_get_gpu_clock_counter(struct amdgpu_device *adev);
static void gfx_v11_0_select_se_sh(struct amdgpu_device *adev, u32 se_num,
       u32 sh_num, u32 instance, int xcc_id);
static u32 gfx_v11_0_get_wgp_active_bitmap_per_sh(struct amdgpu_device *adev);

static void gfx_v11_0_ring_emit_de_meta(struct amdgpu_ring *ring, bool resume);
static void gfx_v11_0_ring_emit_frame_cntl(struct amdgpu_ring *ring, bool start, bool secure);
static void gfx_v11_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
         uint32_t val);
static int gfx_v11_0_wait_for_rlc_autoload_complete(struct amdgpu_device *adev);
static void gfx_v11_0_ring_invalidate_tlbs(struct amdgpu_ring *ring,
        uint16_t pasid, uint32_t flush_type,
        bool all_hub, uint8_t dst_sel);
static void gfx_v11_0_set_safe_mode(struct amdgpu_device *adev, int xcc_id);
static void gfx_v11_0_unset_safe_mode(struct amdgpu_device *adev, int xcc_id);
static void gfx_v11_0_update_perf_clk(struct amdgpu_device *adev,
          bool enable);

static void gfx11_kiq_set_resources(struct amdgpu_ring *kiq_ring, uint64_t queue_mask)
{
 struct amdgpu_device *adev = kiq_ring->adev;
 u64 shader_mc_addr;

 /* Cleaner shader MC address */
 shader_mc_addr = adev->gfx.cleaner_shader_gpu_addr >> 8;

 amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_SET_RESOURCES, 6));
 amdgpu_ring_write(kiq_ring, PACKET3_SET_RESOURCES_VMID_MASK(0) |
     PACKET3_SET_RESOURCES_UNMAP_LATENTY(0xa) | /* unmap_latency: 0xa (~ 1s) */
     PACKET3_SET_RESOURCES_QUEUE_TYPE(0)); /* vmid_mask:0 queue_type:0 (KIQ) */
 amdgpu_ring_write(kiq_ring, lower_32_bits(queue_mask)); /* queue mask lo */
 amdgpu_ring_write(kiq_ring, upper_32_bits(queue_mask)); /* queue mask hi */
 amdgpu_ring_write(kiq_ring, lower_32_bits(shader_mc_addr)); /* cleaner shader addr lo */
 amdgpu_ring_write(kiq_ring, upper_32_bits(shader_mc_addr)); /* cleaner shader addr hi */
 amdgpu_ring_write(kiq_ring, 0); /* oac mask */
 amdgpu_ring_write(kiq_ring, 0); /* gds heap base:0, gds heap size:0 */
}

static void gfx11_kiq_map_queues(struct amdgpu_ring *kiq_ring,
     struct amdgpu_ring *ring)
{
 uint64_t mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj);
 uint64_t wptr_addr = ring->wptr_gpu_addr;
 uint32_t me = 0, eng_sel = 0;

 switch (ring->funcs->type) {
 case AMDGPU_RING_TYPE_COMPUTE:
  me = 1;
  eng_sel = 0;
  break;
 case AMDGPU_RING_TYPE_GFX:
  me = 0;
  eng_sel = 4;
  break;
 case AMDGPU_RING_TYPE_MES:
  me = 2;
  eng_sel = 5;
  break;
 default:
  WARN_ON(1);
 }

 amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_MAP_QUEUES, 5));
 /* Q_sel:0, vmid:0, vidmem: 1, engine:0, num_Q:1*/
 amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
     PACKET3_MAP_QUEUES_QUEUE_SEL(0) | /* Queue_Sel */
     PACKET3_MAP_QUEUES_VMID(0) | /* VMID */
     PACKET3_MAP_QUEUES_QUEUE(ring->queue) |
     PACKET3_MAP_QUEUES_PIPE(ring->pipe) |
     PACKET3_MAP_QUEUES_ME((me)) |
     PACKET3_MAP_QUEUES_QUEUE_TYPE(0) | /*queue_type: normal compute queue */
     PACKET3_MAP_QUEUES_ALLOC_FORMAT(0) | /* alloc format: all_on_one_pipe */
     PACKET3_MAP_QUEUES_ENGINE_SEL(eng_sel) |
     PACKET3_MAP_QUEUES_NUM_QUEUES(1)); /* num_queues: must be 1 */
 amdgpu_ring_write(kiq_ring, PACKET3_MAP_QUEUES_DOORBELL_OFFSET(ring->doorbell_index));
 amdgpu_ring_write(kiq_ring, lower_32_bits(mqd_addr));
 amdgpu_ring_write(kiq_ring, upper_32_bits(mqd_addr));
 amdgpu_ring_write(kiq_ring, lower_32_bits(wptr_addr));
 amdgpu_ring_write(kiq_ring, upper_32_bits(wptr_addr));
}

static void gfx11_kiq_unmap_queues(struct amdgpu_ring *kiq_ring,
       struct amdgpu_ring *ring,
       enum amdgpu_unmap_queues_action action,
       u64 gpu_addr, u64 seq)
{
 struct amdgpu_device *adev = kiq_ring->adev;
 uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;

 if (adev->enable_mes && !adev->gfx.kiq[0].ring.sched.ready) {
  amdgpu_mes_unmap_legacy_queue(adev, ring, action, gpu_addr, seq);
  return;
 }

 amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_UNMAP_QUEUES, 4));
 amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
     PACKET3_UNMAP_QUEUES_ACTION(action) |
     PACKET3_UNMAP_QUEUES_QUEUE_SEL(0) |
     PACKET3_UNMAP_QUEUES_ENGINE_SEL(eng_sel) |
     PACKET3_UNMAP_QUEUES_NUM_QUEUES(1));
 amdgpu_ring_write(kiq_ring,
    PACKET3_UNMAP_QUEUES_DOORBELL_OFFSET0(ring->doorbell_index));

 if (action == PREEMPT_QUEUES_NO_UNMAP) {
  amdgpu_ring_write(kiq_ring, lower_32_bits(gpu_addr));
  amdgpu_ring_write(kiq_ring, upper_32_bits(gpu_addr));
  amdgpu_ring_write(kiq_ring, seq);
 } else {
  amdgpu_ring_write(kiq_ring, 0);
  amdgpu_ring_write(kiq_ring, 0);
  amdgpu_ring_write(kiq_ring, 0);
 }
}

static void gfx11_kiq_query_status(struct amdgpu_ring *kiq_ring,
       struct amdgpu_ring *ring,
       u64 addr,
       u64 seq)
{
 uint32_t eng_sel = ring->funcs->type == AMDGPU_RING_TYPE_GFX ? 4 : 0;

 amdgpu_ring_write(kiq_ring, PACKET3(PACKET3_QUERY_STATUS, 5));
 amdgpu_ring_write(kiq_ring,
     PACKET3_QUERY_STATUS_CONTEXT_ID(0) |
     PACKET3_QUERY_STATUS_INTERRUPT_SEL(0) |
     PACKET3_QUERY_STATUS_COMMAND(2));
 amdgpu_ring_write(kiq_ring, /* Q_sel: 0, vmid: 0, engine: 0, num_Q: 1 */
     PACKET3_QUERY_STATUS_DOORBELL_OFFSET(ring->doorbell_index) |
     PACKET3_QUERY_STATUS_ENG_SEL(eng_sel));
 amdgpu_ring_write(kiq_ring, lower_32_bits(addr));
 amdgpu_ring_write(kiq_ring, upper_32_bits(addr));
 amdgpu_ring_write(kiq_ring, lower_32_bits(seq));
 amdgpu_ring_write(kiq_ring, upper_32_bits(seq));
}

static void gfx11_kiq_invalidate_tlbs(struct amdgpu_ring *kiq_ring,
    uint16_t pasid, uint32_t flush_type,
    bool all_hub)
{
 gfx_v11_0_ring_invalidate_tlbs(kiq_ring, pasid, flush_type, all_hub, 1);
}

static const struct kiq_pm4_funcs gfx_v11_0_kiq_pm4_funcs = {
 .kiq_set_resources = gfx11_kiq_set_resources,
 .kiq_map_queues = gfx11_kiq_map_queues,
 .kiq_unmap_queues = gfx11_kiq_unmap_queues,
 .kiq_query_status = gfx11_kiq_query_status,
 .kiq_invalidate_tlbs = gfx11_kiq_invalidate_tlbs,
 .set_resources_size = 8,
 .map_queues_size = 7,
 .unmap_queues_size = 6,
 .query_status_size = 7,
 .invalidate_tlbs_size = 2,
};

static void gfx_v11_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
{
 adev->gfx.kiq[0].pmf = &gfx_v11_0_kiq_pm4_funcs;
}

static void gfx_v11_0_init_golden_registers(struct amdgpu_device *adev)
{
 if (amdgpu_sriov_vf(adev))
  return;

 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 1):
 case IP_VERSION(11, 0, 4):
  soc15_program_register_sequence(adev,
      golden_settings_gc_11_0_1,
      (const u32)ARRAY_SIZE(golden_settings_gc_11_0_1));
  break;
 default:
  break;
 }
 soc15_program_register_sequence(adev,
     golden_settings_gc_11_0,
     (const u32)ARRAY_SIZE(golden_settings_gc_11_0));

}

static void gfx_v11_0_write_data_to_reg(struct amdgpu_ring *ring, int eng_sel,
           bool wc, uint32_t reg, uint32_t val)
{
 amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
 amdgpu_ring_write(ring, WRITE_DATA_ENGINE_SEL(eng_sel) |
     WRITE_DATA_DST_SEL(0) | (wc ? WR_CONFIRM : 0));
 amdgpu_ring_write(ring, reg);
 amdgpu_ring_write(ring, 0);
 amdgpu_ring_write(ring, val);
}

static void gfx_v11_0_wait_reg_mem(struct amdgpu_ring *ring, int eng_sel,
      int mem_space, int opt, uint32_t addr0,
      uint32_t addr1, uint32_t ref, uint32_t mask,
      uint32_t inv)
{
 amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
 amdgpu_ring_write(ring,
     /* memory (1) or register (0) */
     (WAIT_REG_MEM_MEM_SPACE(mem_space) |
      WAIT_REG_MEM_OPERATION(opt) | /* wait */
      WAIT_REG_MEM_FUNCTION(3) |  /* equal */
      WAIT_REG_MEM_ENGINE(eng_sel)));

 if (mem_space)
  BUG_ON(addr0 & 0x3); /* Dword align */
 amdgpu_ring_write(ring, addr0);
 amdgpu_ring_write(ring, addr1);
 amdgpu_ring_write(ring, ref);
 amdgpu_ring_write(ring, mask);
 amdgpu_ring_write(ring, inv); /* poll interval */
}

static void gfx_v11_ring_insert_nop(struct amdgpu_ring *ring, uint32_t num_nop)
{
 /* Header itself is a NOP packet */
 if (num_nop == 1) {
  amdgpu_ring_write(ring, ring->funcs->nop);
  return;
 }

 /* Max HW optimization till 0x3ffe, followed by remaining one NOP at a time*/
 amdgpu_ring_write(ring, PACKET3(PACKET3_NOP, min(num_nop - 2, 0x3ffe)));

 /* Header is at index 0, followed by num_nops - 1 NOP packet's */
 amdgpu_ring_insert_nop(ring, num_nop - 1);
}

static int gfx_v11_0_ring_test_ring(struct amdgpu_ring *ring)
{
 struct amdgpu_device *adev = ring->adev;
 uint32_t scratch = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG0);
 uint32_t tmp = 0;
 unsigned i;
 int r;

 WREG32(scratch, 0xCAFEDEAD);
 r = amdgpu_ring_alloc(ring, 5);
 if (r) {
  DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n",
     ring->idx, r);
  return r;
 }

 if (ring->funcs->type == AMDGPU_RING_TYPE_KIQ) {
  gfx_v11_0_ring_emit_wreg(ring, scratch, 0xDEADBEEF);
 } else {
  amdgpu_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1));
  amdgpu_ring_write(ring, scratch -
      PACKET3_SET_UCONFIG_REG_START);
  amdgpu_ring_write(ring, 0xDEADBEEF);
 }
 amdgpu_ring_commit(ring);

 for (i = 0; i < adev->usec_timeout; i++) {
  tmp = RREG32(scratch);
  if (tmp == 0xDEADBEEF)
   break;
  if (amdgpu_emu_mode == 1)
   msleep(1);
  else
   udelay(1);
 }

 if (i >= adev->usec_timeout)
  r = -ETIMEDOUT;
 return r;
}

static int gfx_v11_0_ring_test_ib(struct amdgpu_ring *ring, long timeout)
{
 struct amdgpu_device *adev = ring->adev;
 struct amdgpu_ib ib;
 struct dma_fence *f = NULL;
 unsigned index;
 uint64_t gpu_addr;
 volatile uint32_t *cpu_ptr;
 long r;

 /* MES KIQ fw hasn't indirect buffer support for now */
 if (adev->enable_mes_kiq &&
     ring->funcs->type == AMDGPU_RING_TYPE_KIQ)
  return 0;

 memset(&ib, 0, sizeof(ib));

 r = amdgpu_device_wb_get(adev, &index);
 if (r)
  return r;

 gpu_addr = adev->wb.gpu_addr + (index * 4);
 adev->wb.wb[index] = cpu_to_le32(0xCAFEDEAD);
 cpu_ptr = &adev->wb.wb[index];

 r = amdgpu_ib_get(adev, NULL, 20, AMDGPU_IB_POOL_DIRECT, &ib);
 if (r) {
  DRM_ERROR("amdgpu: failed to get ib (%ld).\n", r);
  goto err1;
 }

 ib.ptr[0] = PACKET3(PACKET3_WRITE_DATA, 3);
 ib.ptr[1] = WRITE_DATA_DST_SEL(5) | WR_CONFIRM;
 ib.ptr[2] = lower_32_bits(gpu_addr);
 ib.ptr[3] = upper_32_bits(gpu_addr);
 ib.ptr[4] = 0xDEADBEEF;
 ib.length_dw = 5;

 r = amdgpu_ib_schedule(ring, 1, &ib, NULL, &f);
 if (r)
  goto err2;

 r = dma_fence_wait_timeout(f, false, timeout);
 if (r == 0) {
  r = -ETIMEDOUT;
  goto err2;
 } else if (r < 0) {
  goto err2;
 }

 if (le32_to_cpu(*cpu_ptr) == 0xDEADBEEF)
  r = 0;
 else
  r = -EINVAL;
err2:
 amdgpu_ib_free(&ib, NULL);
 dma_fence_put(f);
err1:
 amdgpu_device_wb_free(adev, index);
 return r;
}

static void gfx_v11_0_free_microcode(struct amdgpu_device *adev)
{
 amdgpu_ucode_release(&adev->gfx.pfp_fw);
 amdgpu_ucode_release(&adev->gfx.me_fw);
 amdgpu_ucode_release(&adev->gfx.rlc_fw);
 amdgpu_ucode_release(&adev->gfx.mec_fw);

 kfree(adev->gfx.rlc.register_list_format);
}

static int gfx_v11_0_init_toc_microcode(struct amdgpu_device *adev, const char *ucode_prefix)
{
 const struct psp_firmware_header_v1_0 *toc_hdr;
 int err = 0;

 err = amdgpu_ucode_request(adev, &adev->psp.toc_fw,
       AMDGPU_UCODE_REQUIRED,
       "amdgpu/%s_toc.bin", ucode_prefix);
 if (err)
  goto out;

 toc_hdr = (const struct psp_firmware_header_v1_0 *)adev->psp.toc_fw->data;
 adev->psp.toc.fw_version = le32_to_cpu(toc_hdr->header.ucode_version);
 adev->psp.toc.feature_version = le32_to_cpu(toc_hdr->sos.fw_version);
 adev->psp.toc.size_bytes = le32_to_cpu(toc_hdr->header.ucode_size_bytes);
 adev->psp.toc.start_addr = (uint8_t *)toc_hdr +
    le32_to_cpu(toc_hdr->header.ucode_array_offset_bytes);
 return 0;
out:
 amdgpu_ucode_release(&adev->psp.toc_fw);
 return err;
}

static void gfx_v11_0_check_fw_cp_gfx_shadow(struct amdgpu_device *adev)
{
 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 2):
 case IP_VERSION(11, 0, 3):
  if ((adev->gfx.me_fw_version >= 1505) &&
      (adev->gfx.pfp_fw_version >= 1600) &&
      (adev->gfx.mec_fw_version >= 512)) {
   if (amdgpu_sriov_vf(adev))
    adev->gfx.cp_gfx_shadow = true;
   else
    adev->gfx.cp_gfx_shadow = false;
  }
  break;
 default:
  adev->gfx.cp_gfx_shadow = false;
  break;
 }
}

static int gfx_v11_0_init_microcode(struct amdgpu_device *adev)
{
 char ucode_prefix[25];
 int err;
 const struct rlc_firmware_header_v2_0 *rlc_hdr;
 uint16_t version_major;
 uint16_t version_minor;

 DRM_DEBUG("\n");

 amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
 err = amdgpu_ucode_request(adev, &adev->gfx.pfp_fw,
       AMDGPU_UCODE_REQUIRED,
       "amdgpu/%s_pfp.bin", ucode_prefix);
 if (err)
  goto out;
 /* check pfp fw hdr version to decide if enable rs64 for gfx11.*/
 adev->gfx.rs64_enable = amdgpu_ucode_hdr_version(
    (union amdgpu_firmware_header *)
    adev->gfx.pfp_fw->data, 2, 0);
 if (adev->gfx.rs64_enable) {
  dev_info(adev->dev, "CP RS64 enable\n");
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK);
 } else {
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_PFP);
 }

 err = amdgpu_ucode_request(adev, &adev->gfx.me_fw,
       AMDGPU_UCODE_REQUIRED,
       "amdgpu/%s_me.bin", ucode_prefix);
 if (err)
  goto out;
 if (adev->gfx.rs64_enable) {
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK);
 } else {
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_ME);
 }

 if (!amdgpu_sriov_vf(adev)) {
  if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 0, 0) &&
      adev->pdev->revision == 0xCE)
   err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw,
         AMDGPU_UCODE_REQUIRED,
         "amdgpu/gc_11_0_0_rlc_1.bin");
  else if (amdgpu_is_kicker_fw(adev))
   err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw,
         AMDGPU_UCODE_REQUIRED,
         "amdgpu/%s_rlc_kicker.bin", ucode_prefix);
  else
   err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw,
         AMDGPU_UCODE_REQUIRED,
         "amdgpu/%s_rlc.bin", ucode_prefix);
  if (err)
   goto out;
  rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data;
  version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
  version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
  err = amdgpu_gfx_rlc_init_microcode(adev, version_major, version_minor);
  if (err)
   goto out;
 }

 err = amdgpu_ucode_request(adev, &adev->gfx.mec_fw,
       AMDGPU_UCODE_REQUIRED,
       "amdgpu/%s_mec.bin", ucode_prefix);
 if (err)
  goto out;
 if (adev->gfx.rs64_enable) {
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK);
 } else {
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1);
  amdgpu_gfx_cp_init_microcode(adev, AMDGPU_UCODE_ID_CP_MEC1_JT);
 }

 if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO)
  err = gfx_v11_0_init_toc_microcode(adev, ucode_prefix);

 /* only one MEC for gfx 11.0.0. */
 adev->gfx.mec2_fw = NULL;

 gfx_v11_0_check_fw_cp_gfx_shadow(adev);

 if (adev->gfx.imu.funcs && adev->gfx.imu.funcs->init_microcode) {
  err = adev->gfx.imu.funcs->init_microcode(adev);
  if (err)
   DRM_ERROR("Failed to init imu firmware!\n");
  return err;
 }

out:
 if (err) {
  amdgpu_ucode_release(&adev->gfx.pfp_fw);
  amdgpu_ucode_release(&adev->gfx.me_fw);
  amdgpu_ucode_release(&adev->gfx.rlc_fw);
  amdgpu_ucode_release(&adev->gfx.mec_fw);
 }

 return err;
}

static u32 gfx_v11_0_get_csb_size(struct amdgpu_device *adev)
{
 u32 count = 0;
 const struct cs_section_def *sect = NULL;
 const struct cs_extent_def *ext = NULL;

 /* begin clear state */
 count += 2;
 /* context control state */
 count += 3;

 for (sect = gfx11_cs_data; sect->section != NULL; ++sect) {
  for (ext = sect->section; ext->extent != NULL; ++ext) {
   if (sect->id == SECT_CONTEXT)
    count += 2 + ext->reg_count;
   else
    return 0;
  }
 }

 /* set PA_SC_TILE_STEERING_OVERRIDE */
 count += 3;
 /* end clear state */
 count += 2;
 /* clear state */
 count += 2;

 return count;
}

static void gfx_v11_0_get_csb_buffer(struct amdgpu_device *adev,
        volatile u32 *buffer)
{
 u32 count = 0;
 int ctx_reg_offset;

 if (adev->gfx.rlc.cs_data == NULL)
  return;
 if (buffer == NULL)
  return;

 count = amdgpu_gfx_csb_preamble_start(buffer);
 count = amdgpu_gfx_csb_data_parser(adev, buffer, count);

 ctx_reg_offset = SOC15_REG_OFFSET(GC, 0, regPA_SC_TILE_STEERING_OVERRIDE) - PACKET3_SET_CONTEXT_REG_START;
 buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
 buffer[count++] = cpu_to_le32(ctx_reg_offset);
 buffer[count++] = cpu_to_le32(adev->gfx.config.pa_sc_tile_steering_override);

 amdgpu_gfx_csb_preamble_end(buffer, count);
}

static void gfx_v11_0_rlc_fini(struct amdgpu_device *adev)
{
 /* clear state block */
 amdgpu_bo_free_kernel(&adev->gfx.rlc.clear_state_obj,
   &adev->gfx.rlc.clear_state_gpu_addr,
   (void **)&adev->gfx.rlc.cs_ptr);

 /* jump table block */
 amdgpu_bo_free_kernel(&adev->gfx.rlc.cp_table_obj,
   &adev->gfx.rlc.cp_table_gpu_addr,
   (void **)&adev->gfx.rlc.cp_table_ptr);
}

static void gfx_v11_0_init_rlcg_reg_access_ctrl(struct amdgpu_device *adev)
{
 struct amdgpu_rlcg_reg_access_ctrl *reg_access_ctrl;

 reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[0];
 reg_access_ctrl->scratch_reg0 = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG0);
 reg_access_ctrl->scratch_reg1 = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG1);
 reg_access_ctrl->scratch_reg2 = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG2);
 reg_access_ctrl->scratch_reg3 = SOC15_REG_OFFSET(GC, 0, regSCRATCH_REG3);
 reg_access_ctrl->grbm_cntl = SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_CNTL);
 reg_access_ctrl->grbm_idx = SOC15_REG_OFFSET(GC, 0, regGRBM_GFX_INDEX);
 reg_access_ctrl->spare_int = SOC15_REG_OFFSET(GC, 0, regRLC_SPARE_INT_0);
 adev->gfx.rlc.rlcg_reg_access_supported = true;
}

static int gfx_v11_0_rlc_init(struct amdgpu_device *adev)
{
 const struct cs_section_def *cs_data;
 int r;

 adev->gfx.rlc.cs_data = gfx11_cs_data;

 cs_data = adev->gfx.rlc.cs_data;

 if (cs_data) {
  /* init clear state block */
  r = amdgpu_gfx_rlc_init_csb(adev);
  if (r)
   return r;
 }

 /* init spm vmid with 0xf */
 if (adev->gfx.rlc.funcs->update_spm_vmid)
  adev->gfx.rlc.funcs->update_spm_vmid(adev, NULL, 0xf);

 return 0;
}

static void gfx_v11_0_mec_fini(struct amdgpu_device *adev)
{
 amdgpu_bo_free_kernel(&adev->gfx.mec.hpd_eop_obj, NULL, NULL);
 amdgpu_bo_free_kernel(&adev->gfx.mec.mec_fw_obj, NULL, NULL);
 amdgpu_bo_free_kernel(&adev->gfx.mec.mec_fw_data_obj, NULL, NULL);
}

static void gfx_v11_0_me_init(struct amdgpu_device *adev)
{
 bitmap_zero(adev->gfx.me.queue_bitmap, AMDGPU_MAX_GFX_QUEUES);

 amdgpu_gfx_graphics_queue_acquire(adev);
}

static int gfx_v11_0_mec_init(struct amdgpu_device *adev)
{
 int r;
 u32 *hpd;
 size_t mec_hpd_size;

 bitmap_zero(adev->gfx.mec_bitmap[0].queue_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);

 /* take ownership of the relevant compute queues */
 amdgpu_gfx_compute_queue_acquire(adev);
 mec_hpd_size = adev->gfx.num_compute_rings * GFX11_MEC_HPD_SIZE;

 if (mec_hpd_size) {
  r = amdgpu_bo_create_reserved(adev, mec_hpd_size, PAGE_SIZE,
           AMDGPU_GEM_DOMAIN_GTT,
           &adev->gfx.mec.hpd_eop_obj,
           &adev->gfx.mec.hpd_eop_gpu_addr,
           (void **)&hpd);
  if (r) {
   dev_warn(adev->dev, "(%d) create HDP EOP bo failed\n", r);
   gfx_v11_0_mec_fini(adev);
   return r;
  }

  memset(hpd, 0, mec_hpd_size);

  amdgpu_bo_kunmap(adev->gfx.mec.hpd_eop_obj);
  amdgpu_bo_unreserve(adev->gfx.mec.hpd_eop_obj);
 }

 return 0;
}

static uint32_t wave_read_ind(struct amdgpu_device *adev, uint32_t wave, uint32_t address)
{
 WREG32_SOC15(GC, 0, regSQ_IND_INDEX,
  (wave << SQ_IND_INDEX__WAVE_ID__SHIFT) |
  (address << SQ_IND_INDEX__INDEX__SHIFT));
 return RREG32_SOC15(GC, 0, regSQ_IND_DATA);
}

static void wave_read_regs(struct amdgpu_device *adev, uint32_t wave,
      uint32_t thread, uint32_t regno,
      uint32_t num, uint32_t *out)
{
 WREG32_SOC15(GC, 0, regSQ_IND_INDEX,
  (wave << SQ_IND_INDEX__WAVE_ID__SHIFT) |
  (regno << SQ_IND_INDEX__INDEX__SHIFT) |
  (thread << SQ_IND_INDEX__WORKITEM_ID__SHIFT) |
  (SQ_IND_INDEX__AUTO_INCR_MASK));
 while (num--)
  *(out++) = RREG32_SOC15(GC, 0, regSQ_IND_DATA);
}

static void gfx_v11_0_read_wave_data(struct amdgpu_device *adev, uint32_t xcc_id, uint32_t simd, uint32_t wave, uint32_t *dst, int *no_fields)
{
 /* in gfx11 the SIMD_ID is specified as part of the INSTANCE
 * field when performing a select_se_sh so it should be
 * zero here */

 WARN_ON(simd != 0);

 /* type 3 wave data */
 dst[(*no_fields)++] = 3;
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_STATUS);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_LO);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_PC_HI);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_EXEC_LO);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_EXEC_HI);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_HW_ID1);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_HW_ID2);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_GPR_ALLOC);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_LDS_ALLOC);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_TRAPSTS);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_STS);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_STS2);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_IB_DBG1);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_M0);
 dst[(*no_fields)++] = wave_read_ind(adev, wave, ixSQ_WAVE_MODE);
}

static void gfx_v11_0_read_wave_sgprs(struct amdgpu_device *adev, uint32_t xcc_id, uint32_t simd,
         uint32_t wave, uint32_t start,
         uint32_t size, uint32_t *dst)
{
 WARN_ON(simd != 0);

 wave_read_regs(
  adev, wave, 0, start + SQIND_WAVE_SGPRS_OFFSET, size,
  dst);
}

static void gfx_v11_0_read_wave_vgprs(struct amdgpu_device *adev, uint32_t xcc_id, uint32_t simd,
          uint32_t wave, uint32_t thread,
          uint32_t start, uint32_t size,
          uint32_t *dst)
{
 wave_read_regs(
  adev, wave, thread,
  start + SQIND_WAVE_VGPRS_OFFSET, size, dst);
}

static void gfx_v11_0_select_me_pipe_q(struct amdgpu_device *adev,
     u32 me, u32 pipe, u32 q, u32 vm, u32 xcc_id)
{
 soc21_grbm_select(adev, me, pipe, q, vm);
}

/* all sizes are in bytes */
#define MQD_SHADOW_BASE_SIZE      73728
#define MQD_SHADOW_BASE_ALIGNMENT 256
#define MQD_FWWORKAREA_SIZE       484
#define MQD_FWWORKAREA_ALIGNMENT  256

static void gfx_v11_0_get_gfx_shadow_info_nocheck(struct amdgpu_device *adev,
      struct amdgpu_gfx_shadow_info *shadow_info)
{
 shadow_info->shadow_size = MQD_SHADOW_BASE_SIZE;
 shadow_info->shadow_alignment = MQD_SHADOW_BASE_ALIGNMENT;
 shadow_info->csa_size = MQD_FWWORKAREA_SIZE;
 shadow_info->csa_alignment = MQD_FWWORKAREA_ALIGNMENT;
}

static int gfx_v11_0_get_gfx_shadow_info(struct amdgpu_device *adev,
      struct amdgpu_gfx_shadow_info *shadow_info,
      bool skip_check)
{
 if (adev->gfx.cp_gfx_shadow || skip_check) {
  gfx_v11_0_get_gfx_shadow_info_nocheck(adev, shadow_info);
  return 0;
 } else {
  memset(shadow_info, 0, sizeof(struct amdgpu_gfx_shadow_info));
  return -ENOTSUPP;
 }
}

static const struct amdgpu_gfx_funcs gfx_v11_0_gfx_funcs = {
 .get_gpu_clock_counter = &gfx_v11_0_get_gpu_clock_counter,
 .select_se_sh = &gfx_v11_0_select_se_sh,
 .read_wave_data = &gfx_v11_0_read_wave_data,
 .read_wave_sgprs = &gfx_v11_0_read_wave_sgprs,
 .read_wave_vgprs = &gfx_v11_0_read_wave_vgprs,
 .select_me_pipe_q = &gfx_v11_0_select_me_pipe_q,
 .update_perfmon_mgcg = &gfx_v11_0_update_perf_clk,
 .get_gfx_shadow_info = &gfx_v11_0_get_gfx_shadow_info,
};

static int gfx_v11_0_gpu_early_init(struct amdgpu_device *adev)
{
 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 2):
  adev->gfx.config.max_hw_contexts = 8;
  adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
  adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
  adev->gfx.config.sc_hiz_tile_fifo_size = 0;
  adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
  break;
 case IP_VERSION(11, 0, 3):
  adev->gfx.ras = &gfx_v11_0_3_ras;
  adev->gfx.config.max_hw_contexts = 8;
  adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
  adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
  adev->gfx.config.sc_hiz_tile_fifo_size = 0;
  adev->gfx.config.sc_earlyz_tile_fifo_size = 0x4C0;
  break;
 case IP_VERSION(11, 0, 1):
 case IP_VERSION(11, 0, 4):
 case IP_VERSION(11, 5, 0):
 case IP_VERSION(11, 5, 1):
 case IP_VERSION(11, 5, 2):
 case IP_VERSION(11, 5, 3):
  adev->gfx.config.max_hw_contexts = 8;
  adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
  adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
  adev->gfx.config.sc_hiz_tile_fifo_size = 0x80;
  adev->gfx.config.sc_earlyz_tile_fifo_size = 0x300;
  break;
 default:
  BUG();
  break;
 }

 return 0;
}

static int gfx_v11_0_gfx_ring_init(struct amdgpu_device *adev, int ring_id,
       int me, int pipe, int queue)
{
 struct amdgpu_ring *ring;
 unsigned int irq_type;
 unsigned int hw_prio;

 ring = &adev->gfx.gfx_ring[ring_id];

 ring->me = me;
 ring->pipe = pipe;
 ring->queue = queue;

 ring->ring_obj = NULL;
 ring->use_doorbell = true;
 if (adev->gfx.disable_kq) {
  ring->no_scheduler = true;
  ring->no_user_submission = true;
 }

 if (!ring_id)
  ring->doorbell_index = adev->doorbell_index.gfx_ring0 << 1;
 else
  ring->doorbell_index = adev->doorbell_index.gfx_ring1 << 1;
 ring->vm_hub = AMDGPU_GFXHUB(0);
 sprintf(ring->name, "gfx_%d.%d.%d", ring->me, ring->pipe, ring->queue);

 irq_type = AMDGPU_CP_IRQ_GFX_ME0_PIPE0_EOP + ring->pipe;
 hw_prio = amdgpu_gfx_is_high_priority_graphics_queue(adev, ring) ?
  AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
 return amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq, irq_type,
    hw_prio, NULL);
}

static int gfx_v11_0_compute_ring_init(struct amdgpu_device *adev, int ring_id,
           int mec, int pipe, int queue)
{
 int r;
 unsigned irq_type;
 struct amdgpu_ring *ring;
 unsigned int hw_prio;

 ring = &adev->gfx.compute_ring[ring_id];

 /* mec0 is me1 */
 ring->me = mec + 1;
 ring->pipe = pipe;
 ring->queue = queue;

 ring->ring_obj = NULL;
 ring->use_doorbell = true;
 ring->doorbell_index = (adev->doorbell_index.mec_ring0 + ring_id) << 1;
 ring->eop_gpu_addr = adev->gfx.mec.hpd_eop_gpu_addr
    + (ring_id * GFX11_MEC_HPD_SIZE);
 ring->vm_hub = AMDGPU_GFXHUB(0);
 sprintf(ring->name, "comp_%d.%d.%d", ring->me, ring->pipe, ring->queue);

 irq_type = AMDGPU_CP_IRQ_COMPUTE_MEC1_PIPE0_EOP
  + ((ring->me - 1) * adev->gfx.mec.num_pipe_per_mec)
  + ring->pipe;
 hw_prio = amdgpu_gfx_is_high_priority_compute_queue(adev, ring) ?
   AMDGPU_GFX_PIPE_PRIO_HIGH : AMDGPU_GFX_PIPE_PRIO_NORMAL;
 /* type-2 packets are deprecated on MEC, use type-3 instead */
 r = amdgpu_ring_init(adev, ring, 1024, &adev->gfx.eop_irq, irq_type,
        hw_prio, NULL);
 if (r)
  return r;

 return 0;
}

static struct {
 SOC21_FIRMWARE_ID id;
 unsigned int  offset;
 unsigned int  size;
} rlc_autoload_info[SOC21_FIRMWARE_ID_MAX];

static void gfx_v11_0_parse_rlc_toc(struct amdgpu_device *adev, void *rlc_toc)
{
 RLC_TABLE_OF_CONTENT *ucode = rlc_toc;

 while (ucode && (ucode->id > SOC21_FIRMWARE_ID_INVALID) &&
   (ucode->id < SOC21_FIRMWARE_ID_MAX)) {
  rlc_autoload_info[ucode->id].id = ucode->id;
  rlc_autoload_info[ucode->id].offset = ucode->offset * 4;
  rlc_autoload_info[ucode->id].size = ucode->size * 4;

  ucode++;
 }
}

static uint32_t gfx_v11_0_calc_toc_total_size(struct amdgpu_device *adev)
{
 uint32_t total_size = 0;
 SOC21_FIRMWARE_ID id;

 gfx_v11_0_parse_rlc_toc(adev, adev->psp.toc.start_addr);

 for (id = SOC21_FIRMWARE_ID_RLC_G_UCODE; id < SOC21_FIRMWARE_ID_MAX; id++)
  total_size += rlc_autoload_info[id].size;

 /* In case the offset in rlc toc ucode is aligned */
 if (total_size < rlc_autoload_info[SOC21_FIRMWARE_ID_MAX-1].offset)
  total_size = rlc_autoload_info[SOC21_FIRMWARE_ID_MAX-1].offset +
   rlc_autoload_info[SOC21_FIRMWARE_ID_MAX-1].size;

 return total_size;
}

static int gfx_v11_0_rlc_autoload_buffer_init(struct amdgpu_device *adev)
{
 int r;
 uint32_t total_size;

 total_size = gfx_v11_0_calc_toc_total_size(adev);

 r = amdgpu_bo_create_reserved(adev, total_size, 64 * 1024,
          AMDGPU_GEM_DOMAIN_VRAM |
          AMDGPU_GEM_DOMAIN_GTT,
          &adev->gfx.rlc.rlc_autoload_bo,
          &adev->gfx.rlc.rlc_autoload_gpu_addr,
          (void **)&adev->gfx.rlc.rlc_autoload_ptr);

 if (r) {
  dev_err(adev->dev, "(%d) failed to create fw autoload bo\n", r);
  return r;
 }

 return 0;
}

static void gfx_v11_0_rlc_backdoor_autoload_copy_ucode(struct amdgpu_device *adev,
           SOC21_FIRMWARE_ID id,
               const void *fw_data,
           uint32_t fw_size,
           uint32_t *fw_autoload_mask)
{
 uint32_t toc_offset;
 uint32_t toc_fw_size;
 char *ptr = adev->gfx.rlc.rlc_autoload_ptr;

 if (id <= SOC21_FIRMWARE_ID_INVALID || id >= SOC21_FIRMWARE_ID_MAX)
  return;

 toc_offset = rlc_autoload_info[id].offset;
 toc_fw_size = rlc_autoload_info[id].size;

 if (fw_size == 0)
  fw_size = toc_fw_size;

 if (fw_size > toc_fw_size)
  fw_size = toc_fw_size;

 memcpy(ptr + toc_offset, fw_data, fw_size);

 if (fw_size < toc_fw_size)
  memset(ptr + toc_offset + fw_size, 0, toc_fw_size - fw_size);

 if ((id != SOC21_FIRMWARE_ID_RS64_PFP) && (id != SOC21_FIRMWARE_ID_RS64_ME))
  *(uint64_t *)fw_autoload_mask |= 1ULL << id;
}

static void gfx_v11_0_rlc_backdoor_autoload_copy_toc_ucode(struct amdgpu_device *adev,
       uint32_t *fw_autoload_mask)
{
 void *data;
 uint32_t size;
 uint64_t *toc_ptr;

 *(uint64_t *)fw_autoload_mask |= 0x1;

 DRM_DEBUG("rlc autoload enabled fw: 0x%llx\n", *(uint64_t *)fw_autoload_mask);

 data = adev->psp.toc.start_addr;
 size = rlc_autoload_info[SOC21_FIRMWARE_ID_RLC_TOC].size;

 toc_ptr = (uint64_t *)data + size / 8 - 1;
 *toc_ptr = *(uint64_t *)fw_autoload_mask;

 gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RLC_TOC,
     data, size, fw_autoload_mask);
}

static void gfx_v11_0_rlc_backdoor_autoload_copy_gfx_ucode(struct amdgpu_device *adev,
       uint32_t *fw_autoload_mask)
{
 const __le32 *fw_data;
 uint32_t fw_size;
 const struct gfx_firmware_header_v1_0 *cp_hdr;
 const struct gfx_firmware_header_v2_0 *cpv2_hdr;
 const struct rlc_firmware_header_v2_0 *rlc_hdr;
 const struct rlc_firmware_header_v2_2 *rlcv22_hdr;
 uint16_t version_major, version_minor;

 if (adev->gfx.rs64_enable) {
  /* pfp ucode */
  cpv2_hdr = (const struct gfx_firmware_header_v2_0 *)
   adev->gfx.pfp_fw->data;
  /* instruction */
  fw_data = (const __le32 *)(adev->gfx.pfp_fw->data +
   le32_to_cpu(cpv2_hdr->ucode_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_PFP,
      fw_data, fw_size, fw_autoload_mask);
  /* data */
  fw_data = (const __le32 *)(adev->gfx.pfp_fw->data +
   le32_to_cpu(cpv2_hdr->data_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_PFP_P0_STACK,
      fw_data, fw_size, fw_autoload_mask);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_PFP_P1_STACK,
      fw_data, fw_size, fw_autoload_mask);
  /* me ucode */
  cpv2_hdr = (const struct gfx_firmware_header_v2_0 *)
   adev->gfx.me_fw->data;
  /* instruction */
  fw_data = (const __le32 *)(adev->gfx.me_fw->data +
   le32_to_cpu(cpv2_hdr->ucode_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_ME,
      fw_data, fw_size, fw_autoload_mask);
  /* data */
  fw_data = (const __le32 *)(adev->gfx.me_fw->data +
   le32_to_cpu(cpv2_hdr->data_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_ME_P0_STACK,
      fw_data, fw_size, fw_autoload_mask);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_ME_P1_STACK,
      fw_data, fw_size, fw_autoload_mask);
  /* mec ucode */
  cpv2_hdr = (const struct gfx_firmware_header_v2_0 *)
   adev->gfx.mec_fw->data;
  /* instruction */
  fw_data = (const __le32 *) (adev->gfx.mec_fw->data +
   le32_to_cpu(cpv2_hdr->ucode_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->ucode_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_MEC,
      fw_data, fw_size, fw_autoload_mask);
  /* data */
  fw_data = (const __le32 *) (adev->gfx.mec_fw->data +
   le32_to_cpu(cpv2_hdr->data_offset_bytes));
  fw_size = le32_to_cpu(cpv2_hdr->data_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_MEC_P0_STACK,
      fw_data, fw_size, fw_autoload_mask);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_MEC_P1_STACK,
      fw_data, fw_size, fw_autoload_mask);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_MEC_P2_STACK,
      fw_data, fw_size, fw_autoload_mask);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RS64_MEC_P3_STACK,
      fw_data, fw_size, fw_autoload_mask);
 } else {
  /* pfp ucode */
  cp_hdr = (const struct gfx_firmware_header_v1_0 *)
   adev->gfx.pfp_fw->data;
  fw_data = (const __le32 *)(adev->gfx.pfp_fw->data +
    le32_to_cpu(cp_hdr->header.ucode_array_offset_bytes));
  fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_CP_PFP,
      fw_data, fw_size, fw_autoload_mask);

  /* me ucode */
  cp_hdr = (const struct gfx_firmware_header_v1_0 *)
   adev->gfx.me_fw->data;
  fw_data = (const __le32 *)(adev->gfx.me_fw->data +
    le32_to_cpu(cp_hdr->header.ucode_array_offset_bytes));
  fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes);
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_CP_ME,
      fw_data, fw_size, fw_autoload_mask);

  /* mec ucode */
  cp_hdr = (const struct gfx_firmware_header_v1_0 *)
   adev->gfx.mec_fw->data;
  fw_data = (const __le32 *) (adev->gfx.mec_fw->data +
    le32_to_cpu(cp_hdr->header.ucode_array_offset_bytes));
  fw_size = le32_to_cpu(cp_hdr->header.ucode_size_bytes) -
   cp_hdr->jt_size * 4;
  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_CP_MEC,
      fw_data, fw_size, fw_autoload_mask);
 }

 /* rlc ucode */
 rlc_hdr = (const struct rlc_firmware_header_v2_0 *)
  adev->gfx.rlc_fw->data;
 fw_data = (const __le32 *)(adev->gfx.rlc_fw->data +
   le32_to_cpu(rlc_hdr->header.ucode_array_offset_bytes));
 fw_size = le32_to_cpu(rlc_hdr->header.ucode_size_bytes);
 gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RLC_G_UCODE,
     fw_data, fw_size, fw_autoload_mask);

 version_major = le16_to_cpu(rlc_hdr->header.header_version_major);
 version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor);
 if (version_major == 2) {
  if (version_minor >= 2) {
   rlcv22_hdr = (const struct rlc_firmware_header_v2_2 *)adev->gfx.rlc_fw->data;

   fw_data = (const __le32 *)(adev->gfx.rlc_fw->data +
     le32_to_cpu(rlcv22_hdr->rlc_iram_ucode_offset_bytes));
   fw_size = le32_to_cpu(rlcv22_hdr->rlc_iram_ucode_size_bytes);
   gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RLX6_UCODE,
     fw_data, fw_size, fw_autoload_mask);

   fw_data = (const __le32 *)(adev->gfx.rlc_fw->data +
     le32_to_cpu(rlcv22_hdr->rlc_dram_ucode_offset_bytes));
   fw_size = le32_to_cpu(rlcv22_hdr->rlc_dram_ucode_size_bytes);
   gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev, SOC21_FIRMWARE_ID_RLX6_DRAM_BOOT,
     fw_data, fw_size, fw_autoload_mask);
  }
 }
}

static void gfx_v11_0_rlc_backdoor_autoload_copy_sdma_ucode(struct amdgpu_device *adev,
       uint32_t *fw_autoload_mask)
{
 const __le32 *fw_data;
 uint32_t fw_size;
 const struct sdma_firmware_header_v2_0 *sdma_hdr;

 sdma_hdr = (const struct sdma_firmware_header_v2_0 *)
  adev->sdma.instance[0].fw->data;
 fw_data = (const __le32 *) (adev->sdma.instance[0].fw->data +
   le32_to_cpu(sdma_hdr->header.ucode_array_offset_bytes));
 fw_size = le32_to_cpu(sdma_hdr->ctx_ucode_size_bytes);

 gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev,
   SOC21_FIRMWARE_ID_SDMA_UCODE_TH0, fw_data, fw_size, fw_autoload_mask);

 fw_data = (const __le32 *) (adev->sdma.instance[0].fw->data +
   le32_to_cpu(sdma_hdr->ctl_ucode_offset));
 fw_size = le32_to_cpu(sdma_hdr->ctl_ucode_size_bytes);

 gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev,
   SOC21_FIRMWARE_ID_SDMA_UCODE_TH1, fw_data, fw_size, fw_autoload_mask);
}

static void gfx_v11_0_rlc_backdoor_autoload_copy_mes_ucode(struct amdgpu_device *adev,
       uint32_t *fw_autoload_mask)
{
 const __le32 *fw_data;
 unsigned fw_size;
 const struct mes_firmware_header_v1_0 *mes_hdr;
 int pipe, ucode_id, data_id;

 for (pipe = 0; pipe < 2; pipe++) {
  if (pipe==0) {
   ucode_id = SOC21_FIRMWARE_ID_RS64_MES_P0;
   data_id  = SOC21_FIRMWARE_ID_RS64_MES_P0_STACK;
  } else {
   ucode_id = SOC21_FIRMWARE_ID_RS64_MES_P1;
   data_id  = SOC21_FIRMWARE_ID_RS64_MES_P1_STACK;
  }

  mes_hdr = (const struct mes_firmware_header_v1_0 *)
   adev->mes.fw[pipe]->data;

  fw_data = (const __le32 *)(adev->mes.fw[pipe]->data +
    le32_to_cpu(mes_hdr->mes_ucode_offset_bytes));
  fw_size = le32_to_cpu(mes_hdr->mes_ucode_size_bytes);

  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev,
    ucode_id, fw_data, fw_size, fw_autoload_mask);

  fw_data = (const __le32 *)(adev->mes.fw[pipe]->data +
    le32_to_cpu(mes_hdr->mes_ucode_data_offset_bytes));
  fw_size = le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes);

  gfx_v11_0_rlc_backdoor_autoload_copy_ucode(adev,
    data_id, fw_data, fw_size, fw_autoload_mask);
 }
}

static int gfx_v11_0_rlc_backdoor_autoload_enable(struct amdgpu_device *adev)
{
 uint32_t rlc_g_offset, rlc_g_size;
 uint64_t gpu_addr;
 uint32_t autoload_fw_id[2];

 memset(autoload_fw_id, 0, sizeof(uint32_t) * 2);

 /* RLC autoload sequence 2: copy ucode */
 gfx_v11_0_rlc_backdoor_autoload_copy_sdma_ucode(adev, autoload_fw_id);
 gfx_v11_0_rlc_backdoor_autoload_copy_gfx_ucode(adev, autoload_fw_id);
 gfx_v11_0_rlc_backdoor_autoload_copy_mes_ucode(adev, autoload_fw_id);
 gfx_v11_0_rlc_backdoor_autoload_copy_toc_ucode(adev, autoload_fw_id);

 rlc_g_offset = rlc_autoload_info[SOC21_FIRMWARE_ID_RLC_G_UCODE].offset;
 rlc_g_size = rlc_autoload_info[SOC21_FIRMWARE_ID_RLC_G_UCODE].size;
 gpu_addr = adev->gfx.rlc.rlc_autoload_gpu_addr + rlc_g_offset;

 WREG32_SOC15(GC, 0, regGFX_IMU_RLC_BOOTLOADER_ADDR_HI, upper_32_bits(gpu_addr));
 WREG32_SOC15(GC, 0, regGFX_IMU_RLC_BOOTLOADER_ADDR_LO, lower_32_bits(gpu_addr));

 WREG32_SOC15(GC, 0, regGFX_IMU_RLC_BOOTLOADER_SIZE, rlc_g_size);

 /* RLC autoload sequence 3: load IMU fw */
 if (adev->gfx.imu.funcs->load_microcode)
  adev->gfx.imu.funcs->load_microcode(adev);
 /* RLC autoload sequence 4 init IMU fw */
 if (adev->gfx.imu.funcs->setup_imu)
  adev->gfx.imu.funcs->setup_imu(adev);
 if (adev->gfx.imu.funcs->start_imu)
  adev->gfx.imu.funcs->start_imu(adev);

 /* RLC autoload sequence 5 disable gpa mode */
 gfx_v11_0_disable_gpa_mode(adev);

 return 0;
}

static void gfx_v11_0_alloc_ip_dump(struct amdgpu_device *adev)
{
 uint32_t reg_count = ARRAY_SIZE(gc_reg_list_11_0);
 uint32_t *ptr;
 uint32_t inst;

 ptr = kcalloc(reg_count, sizeof(uint32_t), GFP_KERNEL);
 if (!ptr) {
  DRM_ERROR("Failed to allocate memory for GFX IP Dump\n");
  adev->gfx.ip_dump_core = NULL;
 } else {
  adev->gfx.ip_dump_core = ptr;
 }

 /* Allocate memory for compute queue registers for all the instances */
 reg_count = ARRAY_SIZE(gc_cp_reg_list_11);
 inst = adev->gfx.mec.num_mec * adev->gfx.mec.num_pipe_per_mec *
  adev->gfx.mec.num_queue_per_pipe;

 ptr = kcalloc(reg_count * inst, sizeof(uint32_t), GFP_KERNEL);
 if (!ptr) {
  DRM_ERROR("Failed to allocate memory for Compute Queues IP Dump\n");
  adev->gfx.ip_dump_compute_queues = NULL;
 } else {
  adev->gfx.ip_dump_compute_queues = ptr;
 }

 /* Allocate memory for gfx queue registers for all the instances */
 reg_count = ARRAY_SIZE(gc_gfx_queue_reg_list_11);
 inst = adev->gfx.me.num_me * adev->gfx.me.num_pipe_per_me *
  adev->gfx.me.num_queue_per_pipe;

 ptr = kcalloc(reg_count * inst, sizeof(uint32_t), GFP_KERNEL);
 if (!ptr) {
  DRM_ERROR("Failed to allocate memory for GFX Queues IP Dump\n");
  adev->gfx.ip_dump_gfx_queues = NULL;
 } else {
  adev->gfx.ip_dump_gfx_queues = ptr;
 }
}

static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
{
 int i, j, k, r, ring_id;
 int xcc_id = 0;
 struct amdgpu_device *adev = ip_block->adev;
 int num_queue_per_pipe = 1; /* we only enable 1 KGQ per pipe */

 INIT_DELAYED_WORK(&adev->gfx.idle_work, amdgpu_gfx_profile_idle_work_handler);

 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 1):
 case IP_VERSION(11, 0, 2):
 case IP_VERSION(11, 0, 3):
 case IP_VERSION(11, 0, 4):
 case IP_VERSION(11, 5, 0):
 case IP_VERSION(11, 5, 1):
 case IP_VERSION(11, 5, 2):
 case IP_VERSION(11, 5, 3):
  adev->gfx.me.num_me = 1;
  adev->gfx.me.num_pipe_per_me = 1;
  adev->gfx.me.num_queue_per_pipe = 2;
  adev->gfx.mec.num_mec = 1;
  adev->gfx.mec.num_pipe_per_mec = 4;
  adev->gfx.mec.num_queue_per_pipe = 4;
  break;
 default:
  adev->gfx.me.num_me = 1;
  adev->gfx.me.num_pipe_per_me = 1;
  adev->gfx.me.num_queue_per_pipe = 1;
  adev->gfx.mec.num_mec = 1;
  adev->gfx.mec.num_pipe_per_mec = 4;
  adev->gfx.mec.num_queue_per_pipe = 8;
  break;
 }

 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 2):
 case IP_VERSION(11, 0, 3):
  if (!adev->gfx.disable_uq &&
      adev->gfx.me_fw_version  >= 2420 &&
      adev->gfx.pfp_fw_version >= 2580 &&
      adev->gfx.mec_fw_version >= 2650 &&
      adev->mes.fw_version[0] >= 120) {
   adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs;
   adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs;
  }
  break;
 case IP_VERSION(11, 0, 1):
 case IP_VERSION(11, 0, 4):
 case IP_VERSION(11, 5, 0):
 case IP_VERSION(11, 5, 1):
 case IP_VERSION(11, 5, 2):
 case IP_VERSION(11, 5, 3):
  /* add firmware version checks here */
  if (0 && !adev->gfx.disable_uq) {
   adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs;
   adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs;
  }
  break;
 default:
  break;
 }

 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 2):
 case IP_VERSION(11, 0, 3):
  adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex;
  adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex);
  if (adev->gfx.me_fw_version  >= 2280 &&
      adev->gfx.pfp_fw_version >= 2370 &&
      adev->gfx.mec_fw_version >= 2450  &&
      adev->mes.fw_version[0] >= 99) {
   adev->gfx.enable_cleaner_shader = true;
   r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
   if (r) {
    adev->gfx.enable_cleaner_shader = false;
    dev_err(adev->dev, "Failed to initialize cleaner shader\n");
   }
  }
  break;
 case IP_VERSION(11, 0, 1):
 case IP_VERSION(11, 0, 4):
  adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex;
  adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex);
  if (adev->gfx.pfp_fw_version >= 102 &&
      adev->gfx.mec_fw_version >= 66 &&
      adev->mes.fw_version[0] >= 128) {
   adev->gfx.enable_cleaner_shader = true;
   r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
   if (r) {
    adev->gfx.enable_cleaner_shader = false;
    dev_err(adev->dev, "Failed to initialize cleaner shader\n");
   }
  }
  break;
 case IP_VERSION(11, 5, 0):
 case IP_VERSION(11, 5, 1):
  adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex;
  adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex);
  if (adev->gfx.mec_fw_version >= 26 &&
      adev->mes.fw_version[0] >= 114) {
   adev->gfx.enable_cleaner_shader = true;
   r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
   if (r) {
    adev->gfx.enable_cleaner_shader = false;
    dev_err(adev->dev, "Failed to initialize cleaner shader\n");
   }
  }
  break;
 case IP_VERSION(11, 5, 2):
  adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex;
  adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex);
  if (adev->gfx.me_fw_version  >= 12 &&
      adev->gfx.pfp_fw_version >= 15 &&
      adev->gfx.mec_fw_version >= 15) {
   adev->gfx.enable_cleaner_shader = true;
   r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
   if (r) {
    adev->gfx.enable_cleaner_shader = false;
    dev_err(adev->dev, "Failed to initialize cleaner shader\n");
   }
  }
  break;
 case IP_VERSION(11, 5, 3):
  adev->gfx.cleaner_shader_ptr = gfx_11_0_3_cleaner_shader_hex;
  adev->gfx.cleaner_shader_size = sizeof(gfx_11_0_3_cleaner_shader_hex);
  if (adev->gfx.me_fw_version  >= 7 &&
      adev->gfx.pfp_fw_version >= 8 &&
      adev->gfx.mec_fw_version >= 8) {
   adev->gfx.enable_cleaner_shader = true;
   r = amdgpu_gfx_cleaner_shader_sw_init(adev, adev->gfx.cleaner_shader_size);
   if (r) {
    adev->gfx.enable_cleaner_shader = false;
    dev_err(adev->dev, "Failed to initialize cleaner shader\n");
   }
  }
  break;
 default:
  adev->gfx.enable_cleaner_shader = false;
  break;
 }

 /* Enable CG flag in one VF mode for enabling RLC safe mode enter/exit */
 if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(11, 0, 3) &&
     amdgpu_sriov_is_pp_one_vf(adev))
  adev->cg_flags = AMD_CG_SUPPORT_GFX_CGCG;

 /* EOP Event */
 r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
         GFX_11_0_0__SRCID__CP_EOP_INTERRUPT,
         &adev->gfx.eop_irq);
 if (r)
  return r;

 /* Bad opcode Event */
 r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
         GFX_11_0_0__SRCID__CP_BAD_OPCODE_ERROR,
         &adev->gfx.bad_op_irq);
 if (r)
  return r;

 /* Privileged reg */
 r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
         GFX_11_0_0__SRCID__CP_PRIV_REG_FAULT,
         &adev->gfx.priv_reg_irq);
 if (r)
  return r;

 /* Privileged inst */
 r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GRBM_CP,
         GFX_11_0_0__SRCID__CP_PRIV_INSTR_FAULT,
         &adev->gfx.priv_inst_irq);
 if (r)
  return r;

 /* FED error */
 r = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_GFX,
      GFX_11_0_0__SRCID__RLC_GC_FED_INTERRUPT,
      &adev->gfx.rlc_gc_fed_irq);
 if (r)
  return r;

 adev->gfx.gfx_current_status = AMDGPU_GFX_NORMAL_MODE;

 gfx_v11_0_me_init(adev);

 r = gfx_v11_0_rlc_init(adev);
 if (r) {
  DRM_ERROR("Failed to init rlc BOs!\n");
  return r;
 }

 r = gfx_v11_0_mec_init(adev);
 if (r) {
  DRM_ERROR("Failed to init MEC BOs!\n");
  return r;
 }

 if (adev->gfx.num_gfx_rings) {
  ring_id = 0;
  /* set up the gfx ring */
  for (i = 0; i < adev->gfx.me.num_me; i++) {
   for (j = 0; j < num_queue_per_pipe; j++) {
    for (k = 0; k < adev->gfx.me.num_pipe_per_me; k++) {
     if (!amdgpu_gfx_is_me_queue_enabled(adev, i, k, j))
      continue;

     r = gfx_v11_0_gfx_ring_init(adev, ring_id,
            i, k, j);
     if (r)
      return r;
     ring_id++;
    }
   }
  }
 }

 if (adev->gfx.num_compute_rings) {
  ring_id = 0;
  /* set up the compute queues - allocate horizontally across pipes */
  for (i = 0; i < adev->gfx.mec.num_mec; ++i) {
   for (j = 0; j < adev->gfx.mec.num_queue_per_pipe; j++) {
    for (k = 0; k < adev->gfx.mec.num_pipe_per_mec; k++) {
     if (!amdgpu_gfx_is_mec_queue_enabled(adev, 0, i,
              k, j))
      continue;

     r = gfx_v11_0_compute_ring_init(adev, ring_id,
         i, k, j);
     if (r)
      return r;

     ring_id++;
    }
   }
  }
 }

 adev->gfx.gfx_supported_reset =
  amdgpu_get_soft_full_reset_mask(&adev->gfx.gfx_ring[0]);
 adev->gfx.compute_supported_reset =
  amdgpu_get_soft_full_reset_mask(&adev->gfx.compute_ring[0]);
 switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 case IP_VERSION(11, 0, 0):
 case IP_VERSION(11, 0, 2):
 case IP_VERSION(11, 0, 3):
  if ((adev->gfx.me_fw_version >= 2280) &&
      (adev->gfx.mec_fw_version >= 2410) &&
      !amdgpu_sriov_vf(adev)) {
   adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
   adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
  }
  break;
 default:
  if (!amdgpu_sriov_vf(adev)) {
   adev->gfx.compute_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
   adev->gfx.gfx_supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
  }
  break;
 }

 if (!adev->enable_mes_kiq) {
  r = amdgpu_gfx_kiq_init(adev, GFX11_MEC_HPD_SIZE, 0);
  if (r) {
   DRM_ERROR("Failed to init KIQ BOs!\n");
   return r;
  }

  r = amdgpu_gfx_kiq_init_ring(adev, xcc_id);
  if (r)
   return r;
 }

 r = amdgpu_gfx_mqd_sw_init(adev, sizeof(struct v11_compute_mqd), 0);
 if (r)
  return r;

 /* allocate visible FB for rlc auto-loading fw */
 if (adev->firmware.load_type == AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO) {
  r = gfx_v11_0_rlc_autoload_buffer_init(adev);
  if (r)
   return r;
 }

 r = gfx_v11_0_gpu_early_init(adev);
 if (r)
  return r;

 if (amdgpu_gfx_ras_sw_init(adev)) {
  dev_err(adev->dev, "Failed to initialize gfx ras block!\n");
  return -EINVAL;
 }

 gfx_v11_0_alloc_ip_dump(adev);

 r = amdgpu_gfx_sysfs_init(adev);
 if (r)
  return r;

 return 0;
}

--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.15 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.