LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/amdgpu - vcn_v2_5.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 713 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 36 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2019 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             : #include <linux/firmware.h>
      25             : #include <drm/drm_drv.h>
      26             : 
      27             : #include "amdgpu.h"
      28             : #include "amdgpu_vcn.h"
      29             : #include "amdgpu_pm.h"
      30             : #include "soc15.h"
      31             : #include "soc15d.h"
      32             : #include "vcn_v2_0.h"
      33             : #include "mmsch_v1_0.h"
      34             : #include "vcn_v2_5.h"
      35             : 
      36             : #include "vcn/vcn_2_5_offset.h"
      37             : #include "vcn/vcn_2_5_sh_mask.h"
      38             : #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
      39             : 
      40             : #define VCN_VID_SOC_ADDRESS_2_0                                 0x1fa00
      41             : #define VCN1_VID_SOC_ADDRESS_3_0                                0x48200
      42             : 
      43             : #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET                        0x27
      44             : #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET                    0x0f
      45             : #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET                  0x10
      46             : #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET                  0x11
      47             : #define mmUVD_NO_OP_INTERNAL_OFFSET                             0x29
      48             : #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET                       0x66
      49             : #define mmUVD_SCRATCH9_INTERNAL_OFFSET                          0xc01d
      50             : 
      51             : #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET                   0x431
      52             : #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET          0x3b4
      53             : #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET         0x3b5
      54             : #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET                       0x25c
      55             : 
      56             : #define VCN25_MAX_HW_INSTANCES_ARCTURUS                 2
      57             : 
      58             : static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
      59             : static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
      60             : static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
      61             : static int vcn_v2_5_set_powergating_state(void *handle,
      62             :                                 enum amd_powergating_state state);
      63             : static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
      64             :                                 int inst_idx, struct dpg_pause_state *new_state);
      65             : static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
      66             : static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev);
      67             : 
      68             : static int amdgpu_ih_clientid_vcns[] = {
      69             :         SOC15_IH_CLIENTID_VCN,
      70             :         SOC15_IH_CLIENTID_VCN1
      71             : };
      72             : 
      73             : /**
      74             :  * vcn_v2_5_early_init - set function pointers
      75             :  *
      76             :  * @handle: amdgpu_device pointer
      77             :  *
      78             :  * Set ring and irq function pointers
      79             :  */
      80           0 : static int vcn_v2_5_early_init(void *handle)
      81             : {
      82           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
      83             : 
      84           0 :         if (amdgpu_sriov_vf(adev)) {
      85           0 :                 adev->vcn.num_vcn_inst = 2;
      86           0 :                 adev->vcn.harvest_config = 0;
      87           0 :                 adev->vcn.num_enc_rings = 1;
      88             :         } else {
      89             :                 u32 harvest;
      90             :                 int i;
      91             : 
      92           0 :                 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
      93           0 :                         harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING);
      94           0 :                         if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
      95           0 :                                 adev->vcn.harvest_config |= 1 << i;
      96             :                 }
      97           0 :                 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
      98             :                                         AMDGPU_VCN_HARVEST_VCN1))
      99             :                         /* both instances are harvested, disable the block */
     100             :                         return -ENOENT;
     101             : 
     102           0 :                 adev->vcn.num_enc_rings = 2;
     103             :         }
     104             : 
     105           0 :         vcn_v2_5_set_dec_ring_funcs(adev);
     106           0 :         vcn_v2_5_set_enc_ring_funcs(adev);
     107           0 :         vcn_v2_5_set_irq_funcs(adev);
     108           0 :         vcn_v2_5_set_ras_funcs(adev);
     109             : 
     110           0 :         return 0;
     111             : }
     112             : 
     113             : /**
     114             :  * vcn_v2_5_sw_init - sw init for VCN block
     115             :  *
     116             :  * @handle: amdgpu_device pointer
     117             :  *
     118             :  * Load firmware and sw initialization
     119             :  */
     120           0 : static int vcn_v2_5_sw_init(void *handle)
     121             : {
     122             :         struct amdgpu_ring *ring;
     123             :         int i, j, r;
     124           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     125             : 
     126           0 :         for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
     127           0 :                 if (adev->vcn.harvest_config & (1 << j))
     128           0 :                         continue;
     129             :                 /* VCN DEC TRAP */
     130           0 :                 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
     131             :                                 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
     132           0 :                 if (r)
     133             :                         return r;
     134             : 
     135             :                 /* VCN ENC TRAP */
     136           0 :                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     137           0 :                         r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
     138           0 :                                 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
     139           0 :                         if (r)
     140             :                                 return r;
     141             :                 }
     142             : 
     143             :                 /* VCN POISON TRAP */
     144           0 :                 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
     145             :                         VCN_2_6__SRCID_UVD_POISON, &adev->vcn.inst[j].irq);
     146           0 :                 if (r)
     147             :                         return r;
     148             :         }
     149             : 
     150           0 :         r = amdgpu_vcn_sw_init(adev);
     151           0 :         if (r)
     152             :                 return r;
     153             : 
     154           0 :         amdgpu_vcn_setup_ucode(adev);
     155             : 
     156           0 :         r = amdgpu_vcn_resume(adev);
     157           0 :         if (r)
     158             :                 return r;
     159             : 
     160           0 :         for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
     161             :                 volatile struct amdgpu_fw_shared *fw_shared;
     162             : 
     163           0 :                 if (adev->vcn.harvest_config & (1 << j))
     164           0 :                         continue;
     165           0 :                 adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
     166           0 :                 adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
     167           0 :                 adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
     168           0 :                 adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
     169           0 :                 adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
     170           0 :                 adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
     171             : 
     172           0 :                 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
     173           0 :                 adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(VCN, j, mmUVD_SCRATCH9);
     174           0 :                 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
     175           0 :                 adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA0);
     176           0 :                 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
     177           0 :                 adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA1);
     178           0 :                 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
     179           0 :                 adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_CMD);
     180           0 :                 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
     181           0 :                 adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(VCN, j, mmUVD_NO_OP);
     182             : 
     183           0 :                 ring = &adev->vcn.inst[j].ring_dec;
     184           0 :                 ring->use_doorbell = true;
     185             : 
     186           0 :                 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
     187           0 :                                 (amdgpu_sriov_vf(adev) ? 2*j : 8*j);
     188           0 :                 sprintf(ring->name, "vcn_dec_%d", j);
     189           0 :                 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq,
     190             :                                      0, AMDGPU_RING_PRIO_DEFAULT, NULL);
     191           0 :                 if (r)
     192             :                         return r;
     193             : 
     194           0 :                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     195           0 :                         enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);
     196             : 
     197           0 :                         ring = &adev->vcn.inst[j].ring_enc[i];
     198           0 :                         ring->use_doorbell = true;
     199             : 
     200           0 :                         ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
     201           0 :                                         (amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j));
     202             : 
     203           0 :                         sprintf(ring->name, "vcn_enc_%d.%d", j, i);
     204           0 :                         r = amdgpu_ring_init(adev, ring, 512,
     205             :                                              &adev->vcn.inst[j].irq, 0,
     206             :                                              hw_prio, NULL);
     207           0 :                         if (r)
     208             :                                 return r;
     209             :                 }
     210             : 
     211           0 :                 fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr;
     212           0 :                 fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
     213             : 
     214           0 :                 if (amdgpu_vcnfw_log)
     215           0 :                         amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
     216             :         }
     217             : 
     218           0 :         if (amdgpu_sriov_vf(adev)) {
     219           0 :                 r = amdgpu_virt_alloc_mm_table(adev);
     220           0 :                 if (r)
     221             :                         return r;
     222             :         }
     223             : 
     224           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
     225           0 :                 adev->vcn.pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
     226             : 
     227             :         return 0;
     228             : }
     229             : 
     230             : /**
     231             :  * vcn_v2_5_sw_fini - sw fini for VCN block
     232             :  *
     233             :  * @handle: amdgpu_device pointer
     234             :  *
     235             :  * VCN suspend and free up sw allocation
     236             :  */
     237           0 : static int vcn_v2_5_sw_fini(void *handle)
     238             : {
     239             :         int i, r, idx;
     240           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     241             :         volatile struct amdgpu_fw_shared *fw_shared;
     242             : 
     243           0 :         if (drm_dev_enter(adev_to_drm(adev), &idx)) {
     244           0 :                 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
     245           0 :                         if (adev->vcn.harvest_config & (1 << i))
     246           0 :                                 continue;
     247           0 :                         fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
     248           0 :                         fw_shared->present_flag_0 = 0;
     249             :                 }
     250           0 :                 drm_dev_exit(idx);
     251             :         }
     252             : 
     253             : 
     254           0 :         if (amdgpu_sriov_vf(adev))
     255           0 :                 amdgpu_virt_free_mm_table(adev);
     256             : 
     257           0 :         r = amdgpu_vcn_suspend(adev);
     258           0 :         if (r)
     259             :                 return r;
     260             : 
     261           0 :         r = amdgpu_vcn_sw_fini(adev);
     262             : 
     263           0 :         return r;
     264             : }
     265             : 
     266             : /**
     267             :  * vcn_v2_5_hw_init - start and test VCN block
     268             :  *
     269             :  * @handle: amdgpu_device pointer
     270             :  *
     271             :  * Initialize the hardware, boot up the VCPU and do some testing
     272             :  */
     273           0 : static int vcn_v2_5_hw_init(void *handle)
     274             : {
     275           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     276             :         struct amdgpu_ring *ring;
     277           0 :         int i, j, r = 0;
     278             : 
     279           0 :         if (amdgpu_sriov_vf(adev))
     280           0 :                 r = vcn_v2_5_sriov_start(adev);
     281             : 
     282           0 :         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
     283           0 :                 if (adev->vcn.harvest_config & (1 << j))
     284           0 :                         continue;
     285             : 
     286           0 :                 if (amdgpu_sriov_vf(adev)) {
     287           0 :                         adev->vcn.inst[j].ring_enc[0].sched.ready = true;
     288           0 :                         adev->vcn.inst[j].ring_enc[1].sched.ready = false;
     289           0 :                         adev->vcn.inst[j].ring_enc[2].sched.ready = false;
     290           0 :                         adev->vcn.inst[j].ring_dec.sched.ready = true;
     291             :                 } else {
     292             : 
     293           0 :                         ring = &adev->vcn.inst[j].ring_dec;
     294             : 
     295           0 :                         adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
     296           0 :                                                      ring->doorbell_index, j);
     297             : 
     298           0 :                         r = amdgpu_ring_test_helper(ring);
     299           0 :                         if (r)
     300             :                                 goto done;
     301             : 
     302           0 :                         for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     303           0 :                                 ring = &adev->vcn.inst[j].ring_enc[i];
     304           0 :                                 r = amdgpu_ring_test_helper(ring);
     305           0 :                                 if (r)
     306             :                                         goto done;
     307             :                         }
     308             :                 }
     309             :         }
     310             : 
     311             : done:
     312           0 :         if (!r)
     313           0 :                 DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
     314             :                         (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
     315             : 
     316           0 :         return r;
     317             : }
     318             : 
     319             : /**
     320             :  * vcn_v2_5_hw_fini - stop the hardware block
     321             :  *
     322             :  * @handle: amdgpu_device pointer
     323             :  *
     324             :  * Stop the VCN block, mark ring as not ready any more
     325             :  */
     326           0 : static int vcn_v2_5_hw_fini(void *handle)
     327             : {
     328           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     329             :         int i;
     330             : 
     331           0 :         cancel_delayed_work_sync(&adev->vcn.idle_work);
     332             : 
     333           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     334           0 :                 if (adev->vcn.harvest_config & (1 << i))
     335           0 :                         continue;
     336             : 
     337           0 :                 if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
     338           0 :                     (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
     339           0 :                      RREG32_SOC15(VCN, i, mmUVD_STATUS)))
     340           0 :                         vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
     341             :         }
     342             : 
     343           0 :         return 0;
     344             : }
     345             : 
     346             : /**
     347             :  * vcn_v2_5_suspend - suspend VCN block
     348             :  *
     349             :  * @handle: amdgpu_device pointer
     350             :  *
     351             :  * HW fini and suspend VCN block
     352             :  */
     353           0 : static int vcn_v2_5_suspend(void *handle)
     354             : {
     355             :         int r;
     356           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     357             : 
     358           0 :         r = vcn_v2_5_hw_fini(adev);
     359           0 :         if (r)
     360             :                 return r;
     361             : 
     362           0 :         r = amdgpu_vcn_suspend(adev);
     363             : 
     364           0 :         return r;
     365             : }
     366             : 
     367             : /**
     368             :  * vcn_v2_5_resume - resume VCN block
     369             :  *
     370             :  * @handle: amdgpu_device pointer
     371             :  *
     372             :  * Resume firmware and hw init VCN block
     373             :  */
     374           0 : static int vcn_v2_5_resume(void *handle)
     375             : {
     376             :         int r;
     377           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     378             : 
     379           0 :         r = amdgpu_vcn_resume(adev);
     380           0 :         if (r)
     381             :                 return r;
     382             : 
     383           0 :         r = vcn_v2_5_hw_init(adev);
     384             : 
     385           0 :         return r;
     386             : }
     387             : 
     388             : /**
     389             :  * vcn_v2_5_mc_resume - memory controller programming
     390             :  *
     391             :  * @adev: amdgpu_device pointer
     392             :  *
     393             :  * Let the VCN memory controller know it's offsets
     394             :  */
     395           0 : static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
     396             : {
     397           0 :         uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
     398             :         uint32_t offset;
     399             :         int i;
     400             : 
     401           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     402           0 :                 if (adev->vcn.harvest_config & (1 << i))
     403           0 :                         continue;
     404             :                 /* cache window 0: fw */
     405           0 :                 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
     406           0 :                         WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     407             :                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo));
     408           0 :                         WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     409             :                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi));
     410           0 :                         WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
     411             :                         offset = 0;
     412             :                 } else {
     413           0 :                         WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     414             :                                 lower_32_bits(adev->vcn.inst[i].gpu_addr));
     415           0 :                         WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     416             :                                 upper_32_bits(adev->vcn.inst[i].gpu_addr));
     417           0 :                         offset = size;
     418           0 :                         WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0,
     419             :                                 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
     420             :                 }
     421           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE0, size);
     422             : 
     423             :                 /* cache window 1: stack */
     424           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
     425             :                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
     426           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
     427             :                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
     428           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
     429           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
     430             : 
     431             :                 /* cache window 2: context */
     432           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
     433             :                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
     434           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
     435             :                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
     436           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
     437           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
     438             : 
     439             :                 /* non-cache window */
     440           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
     441             :                         lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
     442           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
     443             :                         upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
     444           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
     445           0 :                 WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_SIZE0,
     446             :                         AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
     447             :         }
     448           0 : }
     449             : 
     450           0 : static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
     451             : {
     452           0 :         uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
     453             :         uint32_t offset;
     454             : 
     455             :         /* cache window 0: fw */
     456           0 :         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
     457           0 :                 if (!indirect) {
     458           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     459             :                                 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
     460             :                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
     461           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     462             :                                 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
     463             :                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
     464           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     465             :                                 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
     466             :                 } else {
     467           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     468             :                                 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
     469           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     470             :                                 VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
     471           0 :                         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     472             :                                 VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
     473             :                 }
     474             :                 offset = 0;
     475             :         } else {
     476           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     477             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
     478             :                         lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
     479           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     480             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
     481             :                         upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
     482           0 :                 offset = size;
     483           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     484             :                         VCN, 0, mmUVD_VCPU_CACHE_OFFSET0),
     485             :                         AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
     486             :         }
     487             : 
     488           0 :         if (!indirect)
     489           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     490             :                         VCN, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
     491             :         else
     492           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     493             :                         VCN, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
     494             : 
     495             :         /* cache window 1: stack */
     496           0 :         if (!indirect) {
     497           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     498             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
     499             :                         lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
     500           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     501             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
     502             :                         upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
     503           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     504             :                         VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
     505             :         } else {
     506           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     507             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
     508           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     509             :                         VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
     510           0 :                 WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     511             :                         VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
     512             :         }
     513           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     514             :                 VCN, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
     515             : 
     516             :         /* cache window 2: context */
     517           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     518             :                 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
     519             :                 lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
     520           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     521             :                 VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
     522             :                 upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
     523           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     524             :                 VCN, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
     525           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     526             :                 VCN, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
     527             : 
     528             :         /* non-cache window */
     529           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     530             :                 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
     531             :                 lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
     532           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     533             :                 VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
     534             :                 upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
     535           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     536             :                 VCN, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
     537           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     538             :                 VCN, 0, mmUVD_VCPU_NONCACHE_SIZE0),
     539             :                 AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
     540             : 
     541             :         /* VCN global tiling registers */
     542           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     543             :                 VCN, 0, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
     544           0 : }
     545             : 
     546             : /**
     547             :  * vcn_v2_5_disable_clock_gating - disable VCN clock gating
     548             :  *
     549             :  * @adev: amdgpu_device pointer
     550             :  *
     551             :  * Disable clock gating for VCN block
     552             :  */
     553           0 : static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
     554             : {
     555             :         uint32_t data;
     556             :         int i;
     557             : 
     558           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     559           0 :                 if (adev->vcn.harvest_config & (1 << i))
     560           0 :                         continue;
     561             :                 /* UVD disable CGC */
     562           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
     563           0 :                 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     564           0 :                         data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     565             :                 else
     566           0 :                         data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
     567           0 :                 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     568           0 :                 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     569           0 :                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
     570             : 
     571           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
     572           0 :                 data &= ~(UVD_CGC_GATE__SYS_MASK
     573             :                         | UVD_CGC_GATE__UDEC_MASK
     574             :                         | UVD_CGC_GATE__MPEG2_MASK
     575             :                         | UVD_CGC_GATE__REGS_MASK
     576             :                         | UVD_CGC_GATE__RBC_MASK
     577             :                         | UVD_CGC_GATE__LMI_MC_MASK
     578             :                         | UVD_CGC_GATE__LMI_UMC_MASK
     579             :                         | UVD_CGC_GATE__IDCT_MASK
     580             :                         | UVD_CGC_GATE__MPRD_MASK
     581             :                         | UVD_CGC_GATE__MPC_MASK
     582             :                         | UVD_CGC_GATE__LBSI_MASK
     583             :                         | UVD_CGC_GATE__LRBBM_MASK
     584             :                         | UVD_CGC_GATE__UDEC_RE_MASK
     585             :                         | UVD_CGC_GATE__UDEC_CM_MASK
     586             :                         | UVD_CGC_GATE__UDEC_IT_MASK
     587             :                         | UVD_CGC_GATE__UDEC_DB_MASK
     588             :                         | UVD_CGC_GATE__UDEC_MP_MASK
     589             :                         | UVD_CGC_GATE__WCB_MASK
     590             :                         | UVD_CGC_GATE__VCPU_MASK
     591             :                         | UVD_CGC_GATE__MMSCH_MASK);
     592             : 
     593           0 :                 WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
     594             : 
     595           0 :                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0,  0xFFFFFFFF);
     596             : 
     597           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
     598           0 :                 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
     599             :                         | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
     600             :                         | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
     601             :                         | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
     602             :                         | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
     603             :                         | UVD_CGC_CTRL__SYS_MODE_MASK
     604             :                         | UVD_CGC_CTRL__UDEC_MODE_MASK
     605             :                         | UVD_CGC_CTRL__MPEG2_MODE_MASK
     606             :                         | UVD_CGC_CTRL__REGS_MODE_MASK
     607             :                         | UVD_CGC_CTRL__RBC_MODE_MASK
     608             :                         | UVD_CGC_CTRL__LMI_MC_MODE_MASK
     609             :                         | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
     610             :                         | UVD_CGC_CTRL__IDCT_MODE_MASK
     611             :                         | UVD_CGC_CTRL__MPRD_MODE_MASK
     612             :                         | UVD_CGC_CTRL__MPC_MODE_MASK
     613             :                         | UVD_CGC_CTRL__LBSI_MODE_MASK
     614             :                         | UVD_CGC_CTRL__LRBBM_MODE_MASK
     615             :                         | UVD_CGC_CTRL__WCB_MODE_MASK
     616             :                         | UVD_CGC_CTRL__VCPU_MODE_MASK
     617             :                         | UVD_CGC_CTRL__MMSCH_MODE_MASK);
     618           0 :                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
     619             : 
     620             :                 /* turn on */
     621           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
     622           0 :                 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
     623             :                         | UVD_SUVD_CGC_GATE__SIT_MASK
     624             :                         | UVD_SUVD_CGC_GATE__SMP_MASK
     625             :                         | UVD_SUVD_CGC_GATE__SCM_MASK
     626             :                         | UVD_SUVD_CGC_GATE__SDB_MASK
     627             :                         | UVD_SUVD_CGC_GATE__SRE_H264_MASK
     628             :                         | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
     629             :                         | UVD_SUVD_CGC_GATE__SIT_H264_MASK
     630             :                         | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
     631             :                         | UVD_SUVD_CGC_GATE__SCM_H264_MASK
     632             :                         | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
     633             :                         | UVD_SUVD_CGC_GATE__SDB_H264_MASK
     634             :                         | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
     635             :                         | UVD_SUVD_CGC_GATE__SCLR_MASK
     636             :                         | UVD_SUVD_CGC_GATE__UVD_SC_MASK
     637             :                         | UVD_SUVD_CGC_GATE__ENT_MASK
     638             :                         | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
     639             :                         | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
     640             :                         | UVD_SUVD_CGC_GATE__SITE_MASK
     641             :                         | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
     642             :                         | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
     643             :                         | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
     644             :                         | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
     645             :                         | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
     646           0 :                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
     647             : 
     648           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
     649           0 :                 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
     650             :                         | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
     651             :                         | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
     652             :                         | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
     653             :                         | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
     654             :                         | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
     655             :                         | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
     656             :                         | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
     657             :                         | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
     658             :                         | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
     659           0 :                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
     660             :         }
     661           0 : }
     662             : 
     663           0 : static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_device *adev,
     664             :                 uint8_t sram_sel, int inst_idx, uint8_t indirect)
     665             : {
     666           0 :         uint32_t reg_data = 0;
     667             : 
     668             :         /* enable sw clock gating control */
     669           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     670             :                 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     671             :         else
     672           0 :                 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     673           0 :         reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     674           0 :         reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     675           0 :         reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
     676             :                  UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
     677             :                  UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
     678             :                  UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
     679             :                  UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
     680             :                  UVD_CGC_CTRL__SYS_MODE_MASK |
     681             :                  UVD_CGC_CTRL__UDEC_MODE_MASK |
     682             :                  UVD_CGC_CTRL__MPEG2_MODE_MASK |
     683             :                  UVD_CGC_CTRL__REGS_MODE_MASK |
     684             :                  UVD_CGC_CTRL__RBC_MODE_MASK |
     685             :                  UVD_CGC_CTRL__LMI_MC_MODE_MASK |
     686             :                  UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
     687             :                  UVD_CGC_CTRL__IDCT_MODE_MASK |
     688             :                  UVD_CGC_CTRL__MPRD_MODE_MASK |
     689             :                  UVD_CGC_CTRL__MPC_MODE_MASK |
     690             :                  UVD_CGC_CTRL__LBSI_MODE_MASK |
     691             :                  UVD_CGC_CTRL__LRBBM_MODE_MASK |
     692             :                  UVD_CGC_CTRL__WCB_MODE_MASK |
     693             :                  UVD_CGC_CTRL__VCPU_MODE_MASK |
     694             :                  UVD_CGC_CTRL__MMSCH_MODE_MASK);
     695           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     696             :                 VCN, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
     697             : 
     698             :         /* turn off clock gating */
     699           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     700             :                 VCN, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect);
     701             : 
     702             :         /* turn on SUVD clock gating */
     703           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     704             :                 VCN, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
     705             : 
     706             :         /* turn on sw mode in UVD_SUVD_CGC_CTRL */
     707           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     708             :                 VCN, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
     709           0 : }
     710             : 
     711             : /**
     712             :  * vcn_v2_5_enable_clock_gating - enable VCN clock gating
     713             :  *
     714             :  * @adev: amdgpu_device pointer
     715             :  *
     716             :  * Enable clock gating for VCN block
     717             :  */
     718           0 : static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
     719             : {
     720           0 :         uint32_t data = 0;
     721             :         int i;
     722             : 
     723           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     724           0 :                 if (adev->vcn.harvest_config & (1 << i))
     725           0 :                         continue;
     726             :                 /* enable UVD CGC */
     727           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
     728           0 :                 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     729           0 :                         data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     730             :                 else
     731             :                         data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     732           0 :                 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     733           0 :                 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     734           0 :                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
     735             : 
     736           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
     737           0 :                 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
     738             :                         | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
     739             :                         | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
     740             :                         | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
     741             :                         | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
     742             :                         | UVD_CGC_CTRL__SYS_MODE_MASK
     743             :                         | UVD_CGC_CTRL__UDEC_MODE_MASK
     744             :                         | UVD_CGC_CTRL__MPEG2_MODE_MASK
     745             :                         | UVD_CGC_CTRL__REGS_MODE_MASK
     746             :                         | UVD_CGC_CTRL__RBC_MODE_MASK
     747             :                         | UVD_CGC_CTRL__LMI_MC_MODE_MASK
     748             :                         | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
     749             :                         | UVD_CGC_CTRL__IDCT_MODE_MASK
     750             :                         | UVD_CGC_CTRL__MPRD_MODE_MASK
     751             :                         | UVD_CGC_CTRL__MPC_MODE_MASK
     752             :                         | UVD_CGC_CTRL__LBSI_MODE_MASK
     753             :                         | UVD_CGC_CTRL__LRBBM_MODE_MASK
     754             :                         | UVD_CGC_CTRL__WCB_MODE_MASK
     755             :                         | UVD_CGC_CTRL__VCPU_MODE_MASK);
     756           0 :                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
     757             : 
     758           0 :                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
     759           0 :                 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
     760             :                         | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
     761             :                         | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
     762             :                         | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
     763             :                         | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
     764             :                         | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
     765             :                         | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
     766             :                         | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
     767             :                         | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
     768             :                         | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
     769           0 :                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
     770             :         }
     771           0 : }
     772             : 
     773           0 : static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
     774             : {
     775           0 :         volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
     776             :         struct amdgpu_ring *ring;
     777             :         uint32_t rb_bufsz, tmp;
     778             : 
     779             :         /* disable register anti-hang mechanism */
     780           0 :         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
     781             :                 ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
     782             :         /* enable dynamic power gating mode */
     783           0 :         tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
     784           0 :         tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
     785           0 :         tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
     786           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
     787             : 
     788           0 :         if (indirect)
     789           0 :                 adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
     790             : 
     791             :         /* enable clock gating */
     792           0 :         vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
     793             : 
     794             :         /* enable VCPU clock */
     795           0 :         tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
     796           0 :         tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
     797           0 :         tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
     798           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     799             :                 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
     800             : 
     801             :         /* disable master interupt */
     802           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     803             :                 VCN, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
     804             : 
     805             :         /* setup mmUVD_LMI_CTRL */
     806           0 :         tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
     807             :                 UVD_LMI_CTRL__REQ_MODE_MASK |
     808             :                 UVD_LMI_CTRL__CRC_RESET_MASK |
     809             :                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
     810             :                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
     811             :                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
     812             :                 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
     813             :                 0x00100000L);
     814           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     815             :                 VCN, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
     816             : 
     817           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     818             :                 VCN, 0, mmUVD_MPC_CNTL),
     819             :                 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
     820             : 
     821           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     822             :                 VCN, 0, mmUVD_MPC_SET_MUXA0),
     823             :                 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
     824             :                  (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
     825             :                  (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
     826             :                  (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
     827             : 
     828           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     829             :                 VCN, 0, mmUVD_MPC_SET_MUXB0),
     830             :                 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
     831             :                  (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
     832             :                  (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
     833             :                  (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
     834             : 
     835           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     836             :                 VCN, 0, mmUVD_MPC_SET_MUX),
     837             :                 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
     838             :                  (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
     839             :                  (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
     840             : 
     841           0 :         vcn_v2_5_mc_resume_dpg_mode(adev, inst_idx, indirect);
     842             : 
     843           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     844             :                 VCN, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
     845           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     846             :                 VCN, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
     847             : 
     848             :         /* enable LMI MC and UMC channels */
     849           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     850             :                 VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
     851             : 
     852             :         /* unblock VCPU register access */
     853           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     854             :                 VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
     855             : 
     856           0 :         tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
     857           0 :         tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
     858           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     859             :                 VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
     860             : 
     861             :         /* enable master interrupt */
     862           0 :         WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
     863             :                 VCN, 0, mmUVD_MASTINT_EN),
     864             :                 UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
     865             : 
     866           0 :         if (indirect)
     867           0 :                 psp_update_vcn_sram(adev, inst_idx, adev->vcn.inst[inst_idx].dpg_sram_gpu_addr,
     868           0 :                                     (uint32_t)((uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_curr_addr -
     869           0 :                                                (uintptr_t)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr));
     870             : 
     871           0 :         ring = &adev->vcn.inst[inst_idx].ring_dec;
     872             :         /* force RBC into idle state */
     873           0 :         rb_bufsz = order_base_2(ring->ring_size);
     874           0 :         tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
     875           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
     876           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
     877           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
     878           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
     879           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
     880             : 
     881             :         /* Stall DPG before WPTR/RPTR reset */
     882           0 :         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
     883             :                 UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
     884             :                 ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
     885           0 :         fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
     886             : 
     887             :         /* set the write pointer delay */
     888           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
     889             : 
     890             :         /* set the wb address */
     891           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
     892             :                 (upper_32_bits(ring->gpu_addr) >> 2));
     893             : 
     894             :         /* program the RB_BASE for ring buffer */
     895           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
     896             :                 lower_32_bits(ring->gpu_addr));
     897           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
     898             :                 upper_32_bits(ring->gpu_addr));
     899             : 
     900             :         /* Initialize the ring buffer's read and write pointers */
     901           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
     902             : 
     903           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
     904             : 
     905           0 :         ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
     906           0 :         WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
     907             :                 lower_32_bits(ring->wptr));
     908             : 
     909           0 :         fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
     910             :         /* Unstall DPG */
     911           0 :         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
     912             :                 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
     913             : 
     914           0 :         return 0;
     915             : }
     916             : 
     917           0 : static int vcn_v2_5_start(struct amdgpu_device *adev)
     918             : {
     919             :         struct amdgpu_ring *ring;
     920             :         uint32_t rb_bufsz, tmp;
     921             :         int i, j, k, r;
     922             : 
     923           0 :         if (adev->pm.dpm_enabled)
     924           0 :                 amdgpu_dpm_enable_uvd(adev, true);
     925             : 
     926           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     927           0 :                 if (adev->vcn.harvest_config & (1 << i))
     928           0 :                         continue;
     929           0 :                 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
     930           0 :                         r = vcn_v2_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
     931           0 :                         continue;
     932             :                 }
     933             : 
     934             :                 /* disable register anti-hang mechanism */
     935           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 0,
     936             :                         ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
     937             : 
     938             :                 /* set uvd status busy */
     939           0 :                 tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
     940           0 :                 WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
     941             :         }
     942             : 
     943           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
     944             :                 return 0;
     945             : 
     946             :         /*SW clock gating */
     947           0 :         vcn_v2_5_disable_clock_gating(adev);
     948             : 
     949           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     950           0 :                 if (adev->vcn.harvest_config & (1 << i))
     951           0 :                         continue;
     952             :                 /* enable VCPU clock */
     953           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
     954             :                         UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
     955             : 
     956             :                 /* disable master interrupt */
     957           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
     958             :                         ~UVD_MASTINT_EN__VCPU_EN_MASK);
     959             : 
     960             :                 /* setup mmUVD_LMI_CTRL */
     961           0 :                 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
     962           0 :                 tmp &= ~0xff;
     963           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp | 0x8|
     964             :                         UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
     965             :                         UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
     966             :                         UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
     967             :                         UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
     968             : 
     969             :                 /* setup mmUVD_MPC_CNTL */
     970           0 :                 tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
     971           0 :                 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
     972           0 :                 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
     973           0 :                 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
     974             : 
     975             :                 /* setup UVD_MPC_SET_MUXA0 */
     976           0 :                 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
     977             :                         ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
     978             :                         (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
     979             :                         (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
     980             :                         (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
     981             : 
     982             :                 /* setup UVD_MPC_SET_MUXB0 */
     983           0 :                 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
     984             :                         ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
     985             :                         (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
     986             :                         (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
     987             :                         (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
     988             : 
     989             :                 /* setup mmUVD_MPC_SET_MUX */
     990           0 :                 WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
     991             :                         ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
     992             :                         (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
     993             :                         (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
     994             :         }
     995             : 
     996           0 :         vcn_v2_5_mc_resume(adev);
     997             : 
     998           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
     999           0 :                 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
    1000           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1001           0 :                         continue;
    1002             :                 /* VCN global tiling registers */
    1003           0 :                 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
    1004             :                         adev->gfx.config.gb_addr_config);
    1005           0 :                 WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
    1006             :                         adev->gfx.config.gb_addr_config);
    1007             : 
    1008             :                 /* enable LMI MC and UMC channels */
    1009           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
    1010             :                         ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
    1011             : 
    1012             :                 /* unblock VCPU register access */
    1013           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
    1014             :                         ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
    1015             : 
    1016           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
    1017             :                         ~UVD_VCPU_CNTL__BLK_RST_MASK);
    1018             : 
    1019           0 :                 for (k = 0; k < 10; ++k) {
    1020             :                         uint32_t status;
    1021             : 
    1022           0 :                         for (j = 0; j < 100; ++j) {
    1023           0 :                                 status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
    1024           0 :                                 if (status & 2)
    1025             :                                         break;
    1026           0 :                                 if (amdgpu_emu_mode == 1)
    1027           0 :                                         msleep(500);
    1028             :                                 else
    1029           0 :                                         mdelay(10);
    1030             :                         }
    1031           0 :                         r = 0;
    1032           0 :                         if (status & 2)
    1033             :                                 break;
    1034             : 
    1035           0 :                         DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
    1036           0 :                         WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
    1037             :                                 UVD_VCPU_CNTL__BLK_RST_MASK,
    1038             :                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
    1039           0 :                         mdelay(10);
    1040           0 :                         WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
    1041             :                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
    1042             : 
    1043           0 :                         mdelay(10);
    1044           0 :                         r = -1;
    1045             :                 }
    1046             : 
    1047           0 :                 if (r) {
    1048           0 :                         DRM_ERROR("VCN decode not responding, giving up!!!\n");
    1049           0 :                         return r;
    1050             :                 }
    1051             : 
    1052             :                 /* enable master interrupt */
    1053           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
    1054             :                         UVD_MASTINT_EN__VCPU_EN_MASK,
    1055             :                         ~UVD_MASTINT_EN__VCPU_EN_MASK);
    1056             : 
    1057             :                 /* clear the busy bit of VCN_STATUS */
    1058           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
    1059             :                         ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
    1060             : 
    1061           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
    1062             : 
    1063           0 :                 ring = &adev->vcn.inst[i].ring_dec;
    1064             :                 /* force RBC into idle state */
    1065           0 :                 rb_bufsz = order_base_2(ring->ring_size);
    1066           0 :                 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
    1067           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
    1068           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
    1069           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
    1070           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
    1071           0 :                 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
    1072             : 
    1073           0 :                 fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
    1074             :                 /* program the RB_BASE for ring buffer */
    1075           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
    1076             :                         lower_32_bits(ring->gpu_addr));
    1077           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
    1078             :                         upper_32_bits(ring->gpu_addr));
    1079             : 
    1080             :                 /* Initialize the ring buffer's read and write pointers */
    1081           0 :                 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
    1082             : 
    1083           0 :                 ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
    1084           0 :                 WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
    1085             :                                 lower_32_bits(ring->wptr));
    1086           0 :                 fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
    1087             : 
    1088           0 :                 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
    1089           0 :                 ring = &adev->vcn.inst[i].ring_enc[0];
    1090           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
    1091           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
    1092           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
    1093           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
    1094           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
    1095           0 :                 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
    1096             : 
    1097           0 :                 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
    1098           0 :                 ring = &adev->vcn.inst[i].ring_enc[1];
    1099           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
    1100           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
    1101           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
    1102           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
    1103           0 :                 WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
    1104           0 :                 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
    1105             :         }
    1106             : 
    1107             :         return 0;
    1108             : }
    1109             : 
    1110           0 : static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev,
    1111             :                                 struct amdgpu_mm_table *table)
    1112             : {
    1113           0 :         uint32_t data = 0, loop = 0, size = 0;
    1114           0 :         uint64_t addr = table->gpu_addr;
    1115           0 :         struct mmsch_v1_1_init_header *header = NULL;
    1116             : 
    1117           0 :         header = (struct mmsch_v1_1_init_header *)table->cpu_addr;
    1118           0 :         size = header->total_size;
    1119             : 
    1120             :         /*
    1121             :          * 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of
    1122             :          *  memory descriptor location
    1123             :          */
    1124           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
    1125           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
    1126             : 
    1127             :         /* 2, update vmid of descriptor */
    1128           0 :         data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
    1129           0 :         data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
    1130             :         /* use domain0 for MM scheduler */
    1131           0 :         data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
    1132           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, data);
    1133             : 
    1134             :         /* 3, notify mmsch about the size of this descriptor */
    1135           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
    1136             : 
    1137             :         /* 4, set resp to zero */
    1138           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
    1139             : 
    1140             :         /*
    1141             :          * 5, kick off the initialization and wait until
    1142             :          * VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero
    1143             :          */
    1144           0 :         WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, 0x10000001);
    1145             : 
    1146           0 :         data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
    1147             :         loop = 10;
    1148           0 :         while ((data & 0x10000002) != 0x10000002) {
    1149           0 :                 udelay(100);
    1150           0 :                 data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
    1151           0 :                 loop--;
    1152           0 :                 if (!loop)
    1153             :                         break;
    1154             :         }
    1155             : 
    1156           0 :         if (!loop) {
    1157           0 :                 dev_err(adev->dev,
    1158             :                         "failed to init MMSCH, mmMMSCH_VF_MAILBOX_RESP = %x\n",
    1159             :                         data);
    1160             :                 return -EBUSY;
    1161             :         }
    1162             : 
    1163             :         return 0;
    1164             : }
    1165             : 
    1166           0 : static int vcn_v2_5_sriov_start(struct amdgpu_device *adev)
    1167             : {
    1168             :         struct amdgpu_ring *ring;
    1169             :         uint32_t offset, size, tmp, i, rb_bufsz;
    1170           0 :         uint32_t table_size = 0;
    1171           0 :         struct mmsch_v1_0_cmd_direct_write direct_wt = { { 0 } };
    1172           0 :         struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { { 0 } };
    1173           0 :         struct mmsch_v1_0_cmd_end end = { { 0 } };
    1174           0 :         uint32_t *init_table = adev->virt.mm_table.cpu_addr;
    1175           0 :         struct mmsch_v1_1_init_header *header = (struct mmsch_v1_1_init_header *)init_table;
    1176             : 
    1177             :         direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
    1178           0 :         direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
    1179           0 :         end.cmd_header.command_type = MMSCH_COMMAND__END;
    1180             : 
    1181           0 :         header->version = MMSCH_VERSION;
    1182           0 :         header->total_size = sizeof(struct mmsch_v1_1_init_header) >> 2;
    1183           0 :         init_table += header->total_size;
    1184             : 
    1185           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1186           0 :                 header->eng[i].table_offset = header->total_size;
    1187           0 :                 header->eng[i].init_status = 0;
    1188           0 :                 header->eng[i].table_size = 0;
    1189             : 
    1190           0 :                 table_size = 0;
    1191             : 
    1192           0 :                 MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(
    1193             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS),
    1194             :                         ~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
    1195             : 
    1196           0 :                 size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
    1197             :                 /* mc resume*/
    1198           0 :                 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
    1199           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1200             :                                 SOC15_REG_OFFSET(VCN, i,
    1201             :                                         mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
    1202             :                                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
    1203           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1204             :                                 SOC15_REG_OFFSET(VCN, i,
    1205             :                                         mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
    1206             :                                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
    1207           0 :                         offset = 0;
    1208           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1209             :                                 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 0);
    1210             :                 } else {
    1211           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1212             :                                 SOC15_REG_OFFSET(VCN, i,
    1213             :                                         mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
    1214             :                                 lower_32_bits(adev->vcn.inst[i].gpu_addr));
    1215           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1216             :                                 SOC15_REG_OFFSET(VCN, i,
    1217             :                                         mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
    1218             :                                 upper_32_bits(adev->vcn.inst[i].gpu_addr));
    1219           0 :                         offset = size;
    1220           0 :                         MMSCH_V1_0_INSERT_DIRECT_WT(
    1221             :                                 SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0),
    1222             :                                 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
    1223             :                 }
    1224             : 
    1225           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1226             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE0),
    1227             :                         size);
    1228           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1229             :                         SOC15_REG_OFFSET(VCN, i,
    1230             :                                 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
    1231             :                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
    1232           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1233             :                         SOC15_REG_OFFSET(VCN, i,
    1234             :                                 mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
    1235             :                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
    1236           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1237             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET1),
    1238             :                         0);
    1239           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1240             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE1),
    1241             :                         AMDGPU_VCN_STACK_SIZE);
    1242           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1243             :                         SOC15_REG_OFFSET(VCN, i,
    1244             :                                 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
    1245             :                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset +
    1246             :                                 AMDGPU_VCN_STACK_SIZE));
    1247           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1248             :                         SOC15_REG_OFFSET(VCN, i,
    1249             :                                 mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
    1250             :                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset +
    1251             :                                 AMDGPU_VCN_STACK_SIZE));
    1252           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1253             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET2),
    1254             :                         0);
    1255           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1256             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE2),
    1257             :                         AMDGPU_VCN_CONTEXT_SIZE);
    1258             : 
    1259           0 :                 ring = &adev->vcn.inst[i].ring_enc[0];
    1260           0 :                 ring->wptr = 0;
    1261             : 
    1262           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1263             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_LO),
    1264             :                         lower_32_bits(ring->gpu_addr));
    1265           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1266             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_HI),
    1267             :                         upper_32_bits(ring->gpu_addr));
    1268           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1269             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_RB_SIZE),
    1270             :                         ring->ring_size / 4);
    1271             : 
    1272           0 :                 ring = &adev->vcn.inst[i].ring_dec;
    1273           0 :                 ring->wptr = 0;
    1274           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1275             :                         SOC15_REG_OFFSET(VCN, i,
    1276             :                                 mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
    1277             :                         lower_32_bits(ring->gpu_addr));
    1278           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1279             :                         SOC15_REG_OFFSET(VCN, i,
    1280             :                                 mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
    1281             :                         upper_32_bits(ring->gpu_addr));
    1282             : 
    1283             :                 /* force RBC into idle state */
    1284           0 :                 rb_bufsz = order_base_2(ring->ring_size);
    1285           0 :                 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
    1286           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
    1287           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
    1288           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
    1289           0 :                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
    1290           0 :                 MMSCH_V1_0_INSERT_DIRECT_WT(
    1291             :                         SOC15_REG_OFFSET(VCN, i, mmUVD_RBC_RB_CNTL), tmp);
    1292             : 
    1293             :                 /* add end packet */
    1294           0 :                 memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
    1295           0 :                 table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
    1296           0 :                 init_table += sizeof(struct mmsch_v1_0_cmd_end) / 4;
    1297             : 
    1298             :                 /* refine header */
    1299           0 :                 header->eng[i].table_size = table_size;
    1300           0 :                 header->total_size += table_size;
    1301             :         }
    1302             : 
    1303           0 :         return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table);
    1304             : }
    1305             : 
    1306           0 : static int vcn_v2_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
    1307             : {
    1308             :         uint32_t tmp;
    1309             : 
    1310             :         /* Wait for power status to be 1 */
    1311           0 :         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
    1312             :                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1313             : 
    1314             :         /* wait for read ptr to be equal to write ptr */
    1315           0 :         tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
    1316           0 :         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
    1317             : 
    1318           0 :         tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
    1319           0 :         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
    1320             : 
    1321           0 :         tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
    1322           0 :         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
    1323             : 
    1324           0 :         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
    1325             :                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1326             : 
    1327             :         /* disable dynamic power gating mode */
    1328           0 :         WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
    1329             :                         ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
    1330             : 
    1331           0 :         return 0;
    1332             : }
    1333             : 
    1334           0 : static int vcn_v2_5_stop(struct amdgpu_device *adev)
    1335             : {
    1336             :         uint32_t tmp;
    1337           0 :         int i, r = 0;
    1338             : 
    1339           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1340           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1341           0 :                         continue;
    1342           0 :                 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
    1343           0 :                         r = vcn_v2_5_stop_dpg_mode(adev, i);
    1344           0 :                         continue;
    1345             :                 }
    1346             : 
    1347             :                 /* wait for vcn idle */
    1348           0 :                 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
    1349           0 :                 if (r)
    1350             :                         return r;
    1351             : 
    1352           0 :                 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
    1353             :                         UVD_LMI_STATUS__READ_CLEAN_MASK |
    1354             :                         UVD_LMI_STATUS__WRITE_CLEAN_MASK |
    1355             :                         UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
    1356           0 :                 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
    1357           0 :                 if (r)
    1358             :                         return r;
    1359             : 
    1360             :                 /* block LMI UMC channel */
    1361           0 :                 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
    1362           0 :                 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
    1363           0 :                 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
    1364             : 
    1365           0 :                 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
    1366             :                         UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
    1367           0 :                 r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
    1368           0 :                 if (r)
    1369             :                         return r;
    1370             : 
    1371             :                 /* block VCPU register access */
    1372           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
    1373             :                         UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
    1374             :                         ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
    1375             : 
    1376             :                 /* reset VCPU */
    1377           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
    1378             :                         UVD_VCPU_CNTL__BLK_RST_MASK,
    1379             :                         ~UVD_VCPU_CNTL__BLK_RST_MASK);
    1380             : 
    1381             :                 /* disable VCPU clock */
    1382           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
    1383             :                         ~(UVD_VCPU_CNTL__CLK_EN_MASK));
    1384             : 
    1385             :                 /* clear status */
    1386           0 :                 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
    1387             : 
    1388           0 :                 vcn_v2_5_enable_clock_gating(adev);
    1389             : 
    1390             :                 /* enable register anti-hang mechanism */
    1391           0 :                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS),
    1392             :                         UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
    1393             :                         ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1394             :         }
    1395             : 
    1396           0 :         if (adev->pm.dpm_enabled)
    1397           0 :                 amdgpu_dpm_enable_uvd(adev, false);
    1398             : 
    1399             :         return 0;
    1400             : }
    1401             : 
    1402           0 : static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
    1403             :                                 int inst_idx, struct dpg_pause_state *new_state)
    1404             : {
    1405             :         struct amdgpu_ring *ring;
    1406           0 :         uint32_t reg_data = 0;
    1407           0 :         int ret_code = 0;
    1408             : 
    1409             :         /* pause/unpause if state is changed */
    1410           0 :         if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
    1411           0 :                 DRM_DEBUG("dpg pause state changed %d -> %d",
    1412             :                         adev->vcn.inst[inst_idx].pause_state.fw_based,       new_state->fw_based);
    1413           0 :                 reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
    1414             :                         (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
    1415             : 
    1416           0 :                 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
    1417           0 :                         ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
    1418             :                                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1419             : 
    1420           0 :                         if (!ret_code) {
    1421           0 :                                 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
    1422             : 
    1423             :                                 /* pause DPG */
    1424           0 :                                 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
    1425           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
    1426             : 
    1427             :                                 /* wait for ACK */
    1428           0 :                                 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
    1429             :                                            UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
    1430             :                                            UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
    1431             : 
    1432             :                                 /* Stall DPG before WPTR/RPTR reset */
    1433           0 :                                 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
    1434             :                                            UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
    1435             :                                            ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
    1436             : 
    1437             :                                 /* Restore */
    1438           0 :                                 fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
    1439           0 :                                 ring = &adev->vcn.inst[inst_idx].ring_enc[0];
    1440           0 :                                 ring->wptr = 0;
    1441           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
    1442           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
    1443           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
    1444           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
    1445           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
    1446           0 :                                 fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
    1447             : 
    1448           0 :                                 fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
    1449           0 :                                 ring = &adev->vcn.inst[inst_idx].ring_enc[1];
    1450           0 :                                 ring->wptr = 0;
    1451           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
    1452           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
    1453           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
    1454           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
    1455           0 :                                 WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
    1456           0 :                                 fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
    1457             : 
    1458             :                                 /* Unstall DPG */
    1459           0 :                                 WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
    1460             :                                            0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
    1461             : 
    1462           0 :                                 SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
    1463             :                                            UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1464             :                         }
    1465             :                 } else {
    1466           0 :                         reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
    1467           0 :                         WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
    1468           0 :                         SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
    1469             :                                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1470             :                 }
    1471           0 :                 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
    1472             :         }
    1473             : 
    1474           0 :         return 0;
    1475             : }
    1476             : 
    1477             : /**
    1478             :  * vcn_v2_5_dec_ring_get_rptr - get read pointer
    1479             :  *
    1480             :  * @ring: amdgpu_ring pointer
    1481             :  *
    1482             :  * Returns the current hardware read pointer
    1483             :  */
    1484           0 : static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
    1485             : {
    1486           0 :         struct amdgpu_device *adev = ring->adev;
    1487             : 
    1488           0 :         return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
    1489             : }
    1490             : 
    1491             : /**
    1492             :  * vcn_v2_5_dec_ring_get_wptr - get write pointer
    1493             :  *
    1494             :  * @ring: amdgpu_ring pointer
    1495             :  *
    1496             :  * Returns the current hardware write pointer
    1497             :  */
    1498           0 : static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
    1499             : {
    1500           0 :         struct amdgpu_device *adev = ring->adev;
    1501             : 
    1502           0 :         if (ring->use_doorbell)
    1503           0 :                 return *ring->wptr_cpu_addr;
    1504             :         else
    1505           0 :                 return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
    1506             : }
    1507             : 
    1508             : /**
    1509             :  * vcn_v2_5_dec_ring_set_wptr - set write pointer
    1510             :  *
    1511             :  * @ring: amdgpu_ring pointer
    1512             :  *
    1513             :  * Commits the write pointer to the hardware
    1514             :  */
    1515           0 : static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
    1516             : {
    1517           0 :         struct amdgpu_device *adev = ring->adev;
    1518             : 
    1519           0 :         if (ring->use_doorbell) {
    1520           0 :                 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
    1521           0 :                 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
    1522             :         } else {
    1523           0 :                 WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
    1524             :         }
    1525           0 : }
    1526             : 
    1527             : static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
    1528             :         .type = AMDGPU_RING_TYPE_VCN_DEC,
    1529             :         .align_mask = 0xf,
    1530             :         .secure_submission_supported = true,
    1531             :         .vmhub = AMDGPU_MMHUB_1,
    1532             :         .get_rptr = vcn_v2_5_dec_ring_get_rptr,
    1533             :         .get_wptr = vcn_v2_5_dec_ring_get_wptr,
    1534             :         .set_wptr = vcn_v2_5_dec_ring_set_wptr,
    1535             :         .emit_frame_size =
    1536             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
    1537             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
    1538             :                 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
    1539             :                 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
    1540             :                 6,
    1541             :         .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
    1542             :         .emit_ib = vcn_v2_0_dec_ring_emit_ib,
    1543             :         .emit_fence = vcn_v2_0_dec_ring_emit_fence,
    1544             :         .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
    1545             :         .test_ring = vcn_v2_0_dec_ring_test_ring,
    1546             :         .test_ib = amdgpu_vcn_dec_ring_test_ib,
    1547             :         .insert_nop = vcn_v2_0_dec_ring_insert_nop,
    1548             :         .insert_start = vcn_v2_0_dec_ring_insert_start,
    1549             :         .insert_end = vcn_v2_0_dec_ring_insert_end,
    1550             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    1551             :         .begin_use = amdgpu_vcn_ring_begin_use,
    1552             :         .end_use = amdgpu_vcn_ring_end_use,
    1553             :         .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
    1554             :         .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
    1555             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    1556             : };
    1557             : 
    1558             : static const struct amdgpu_ring_funcs vcn_v2_6_dec_ring_vm_funcs = {
    1559             :         .type = AMDGPU_RING_TYPE_VCN_DEC,
    1560             :         .align_mask = 0xf,
    1561             :         .secure_submission_supported = true,
    1562             :         .vmhub = AMDGPU_MMHUB_0,
    1563             :         .get_rptr = vcn_v2_5_dec_ring_get_rptr,
    1564             :         .get_wptr = vcn_v2_5_dec_ring_get_wptr,
    1565             :         .set_wptr = vcn_v2_5_dec_ring_set_wptr,
    1566             :         .emit_frame_size =
    1567             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
    1568             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
    1569             :                 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
    1570             :                 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
    1571             :                 6,
    1572             :         .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
    1573             :         .emit_ib = vcn_v2_0_dec_ring_emit_ib,
    1574             :         .emit_fence = vcn_v2_0_dec_ring_emit_fence,
    1575             :         .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
    1576             :         .test_ring = vcn_v2_0_dec_ring_test_ring,
    1577             :         .test_ib = amdgpu_vcn_dec_ring_test_ib,
    1578             :         .insert_nop = vcn_v2_0_dec_ring_insert_nop,
    1579             :         .insert_start = vcn_v2_0_dec_ring_insert_start,
    1580             :         .insert_end = vcn_v2_0_dec_ring_insert_end,
    1581             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    1582             :         .begin_use = amdgpu_vcn_ring_begin_use,
    1583             :         .end_use = amdgpu_vcn_ring_end_use,
    1584             :         .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
    1585             :         .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
    1586             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    1587             : };
    1588             : 
    1589             : /**
    1590             :  * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
    1591             :  *
    1592             :  * @ring: amdgpu_ring pointer
    1593             :  *
    1594             :  * Returns the current hardware enc read pointer
    1595             :  */
    1596           0 : static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
    1597             : {
    1598           0 :         struct amdgpu_device *adev = ring->adev;
    1599             : 
    1600           0 :         if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
    1601           0 :                 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
    1602             :         else
    1603           0 :                 return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
    1604             : }
    1605             : 
    1606             : /**
    1607             :  * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
    1608             :  *
    1609             :  * @ring: amdgpu_ring pointer
    1610             :  *
    1611             :  * Returns the current hardware enc write pointer
    1612             :  */
    1613           0 : static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
    1614             : {
    1615           0 :         struct amdgpu_device *adev = ring->adev;
    1616             : 
    1617           0 :         if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
    1618           0 :                 if (ring->use_doorbell)
    1619           0 :                         return *ring->wptr_cpu_addr;
    1620             :                 else
    1621           0 :                         return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
    1622             :         } else {
    1623           0 :                 if (ring->use_doorbell)
    1624           0 :                         return *ring->wptr_cpu_addr;
    1625             :                 else
    1626           0 :                         return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
    1627             :         }
    1628             : }
    1629             : 
    1630             : /**
    1631             :  * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
    1632             :  *
    1633             :  * @ring: amdgpu_ring pointer
    1634             :  *
    1635             :  * Commits the enc write pointer to the hardware
    1636             :  */
    1637           0 : static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
    1638             : {
    1639           0 :         struct amdgpu_device *adev = ring->adev;
    1640             : 
    1641           0 :         if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
    1642           0 :                 if (ring->use_doorbell) {
    1643           0 :                         *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
    1644           0 :                         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
    1645             :                 } else {
    1646           0 :                         WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
    1647             :                 }
    1648             :         } else {
    1649           0 :                 if (ring->use_doorbell) {
    1650           0 :                         *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
    1651           0 :                         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
    1652             :                 } else {
    1653           0 :                         WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
    1654             :                 }
    1655             :         }
    1656           0 : }
    1657             : 
    1658             : static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
    1659             :         .type = AMDGPU_RING_TYPE_VCN_ENC,
    1660             :         .align_mask = 0x3f,
    1661             :         .nop = VCN_ENC_CMD_NO_OP,
    1662             :         .vmhub = AMDGPU_MMHUB_1,
    1663             :         .get_rptr = vcn_v2_5_enc_ring_get_rptr,
    1664             :         .get_wptr = vcn_v2_5_enc_ring_get_wptr,
    1665             :         .set_wptr = vcn_v2_5_enc_ring_set_wptr,
    1666             :         .emit_frame_size =
    1667             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
    1668             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
    1669             :                 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
    1670             :                 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
    1671             :                 1, /* vcn_v2_0_enc_ring_insert_end */
    1672             :         .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
    1673             :         .emit_ib = vcn_v2_0_enc_ring_emit_ib,
    1674             :         .emit_fence = vcn_v2_0_enc_ring_emit_fence,
    1675             :         .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
    1676             :         .test_ring = amdgpu_vcn_enc_ring_test_ring,
    1677             :         .test_ib = amdgpu_vcn_enc_ring_test_ib,
    1678             :         .insert_nop = amdgpu_ring_insert_nop,
    1679             :         .insert_end = vcn_v2_0_enc_ring_insert_end,
    1680             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    1681             :         .begin_use = amdgpu_vcn_ring_begin_use,
    1682             :         .end_use = amdgpu_vcn_ring_end_use,
    1683             :         .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
    1684             :         .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
    1685             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    1686             : };
    1687             : 
    1688             : static const struct amdgpu_ring_funcs vcn_v2_6_enc_ring_vm_funcs = {
    1689             :         .type = AMDGPU_RING_TYPE_VCN_ENC,
    1690             :         .align_mask = 0x3f,
    1691             :         .nop = VCN_ENC_CMD_NO_OP,
    1692             :         .vmhub = AMDGPU_MMHUB_0,
    1693             :         .get_rptr = vcn_v2_5_enc_ring_get_rptr,
    1694             :         .get_wptr = vcn_v2_5_enc_ring_get_wptr,
    1695             :         .set_wptr = vcn_v2_5_enc_ring_set_wptr,
    1696             :         .emit_frame_size =
    1697             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
    1698             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
    1699             :                 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
    1700             :                 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
    1701             :                 1, /* vcn_v2_0_enc_ring_insert_end */
    1702             :         .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
    1703             :         .emit_ib = vcn_v2_0_enc_ring_emit_ib,
    1704             :         .emit_fence = vcn_v2_0_enc_ring_emit_fence,
    1705             :         .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
    1706             :         .test_ring = amdgpu_vcn_enc_ring_test_ring,
    1707             :         .test_ib = amdgpu_vcn_enc_ring_test_ib,
    1708             :         .insert_nop = amdgpu_ring_insert_nop,
    1709             :         .insert_end = vcn_v2_0_enc_ring_insert_end,
    1710             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    1711             :         .begin_use = amdgpu_vcn_ring_begin_use,
    1712             :         .end_use = amdgpu_vcn_ring_end_use,
    1713             :         .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
    1714             :         .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
    1715             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    1716             : };
    1717             : 
    1718           0 : static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
    1719             : {
    1720             :         int i;
    1721             : 
    1722           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1723           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1724           0 :                         continue;
    1725           0 :                 if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0))
    1726           0 :                         adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
    1727             :                 else /* CHIP_ALDEBARAN */
    1728           0 :                         adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_6_dec_ring_vm_funcs;
    1729           0 :                 adev->vcn.inst[i].ring_dec.me = i;
    1730           0 :                 DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
    1731             :         }
    1732           0 : }
    1733             : 
    1734           0 : static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
    1735             : {
    1736             :         int i, j;
    1737             : 
    1738           0 :         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
    1739           0 :                 if (adev->vcn.harvest_config & (1 << j))
    1740           0 :                         continue;
    1741           0 :                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
    1742           0 :                         if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0))
    1743           0 :                                 adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
    1744             :                         else /* CHIP_ALDEBARAN */
    1745           0 :                                 adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_6_enc_ring_vm_funcs;
    1746           0 :                         adev->vcn.inst[j].ring_enc[i].me = j;
    1747             :                 }
    1748           0 :                 DRM_INFO("VCN(%d) encode is enabled in VM mode\n", j);
    1749             :         }
    1750           0 : }
    1751             : 
    1752           0 : static bool vcn_v2_5_is_idle(void *handle)
    1753             : {
    1754           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1755           0 :         int i, ret = 1;
    1756             : 
    1757           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1758           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1759           0 :                         continue;
    1760           0 :                 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
    1761             :         }
    1762             : 
    1763           0 :         return ret;
    1764             : }
    1765             : 
    1766           0 : static int vcn_v2_5_wait_for_idle(void *handle)
    1767             : {
    1768           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1769           0 :         int i, ret = 0;
    1770             : 
    1771           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1772           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1773           0 :                         continue;
    1774           0 :                 ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
    1775             :                         UVD_STATUS__IDLE);
    1776           0 :                 if (ret)
    1777             :                         return ret;
    1778             :         }
    1779             : 
    1780             :         return ret;
    1781             : }
    1782             : 
    1783           0 : static int vcn_v2_5_set_clockgating_state(void *handle,
    1784             :                                           enum amd_clockgating_state state)
    1785             : {
    1786           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1787           0 :         bool enable = (state == AMD_CG_STATE_GATE);
    1788             : 
    1789           0 :         if (amdgpu_sriov_vf(adev))
    1790             :                 return 0;
    1791             : 
    1792           0 :         if (enable) {
    1793           0 :                 if (!vcn_v2_5_is_idle(handle))
    1794             :                         return -EBUSY;
    1795           0 :                 vcn_v2_5_enable_clock_gating(adev);
    1796             :         } else {
    1797           0 :                 vcn_v2_5_disable_clock_gating(adev);
    1798             :         }
    1799             : 
    1800             :         return 0;
    1801             : }
    1802             : 
    1803           0 : static int vcn_v2_5_set_powergating_state(void *handle,
    1804             :                                           enum amd_powergating_state state)
    1805             : {
    1806           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1807             :         int ret;
    1808             : 
    1809           0 :         if (amdgpu_sriov_vf(adev))
    1810             :                 return 0;
    1811             : 
    1812           0 :         if(state == adev->vcn.cur_state)
    1813             :                 return 0;
    1814             : 
    1815           0 :         if (state == AMD_PG_STATE_GATE)
    1816           0 :                 ret = vcn_v2_5_stop(adev);
    1817             :         else
    1818           0 :                 ret = vcn_v2_5_start(adev);
    1819             : 
    1820           0 :         if(!ret)
    1821           0 :                 adev->vcn.cur_state = state;
    1822             : 
    1823             :         return ret;
    1824             : }
    1825             : 
    1826           0 : static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
    1827             :                                         struct amdgpu_irq_src *source,
    1828             :                                         unsigned type,
    1829             :                                         enum amdgpu_interrupt_state state)
    1830             : {
    1831           0 :         return 0;
    1832             : }
    1833             : 
    1834           0 : static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
    1835             :                                       struct amdgpu_irq_src *source,
    1836             :                                       struct amdgpu_iv_entry *entry)
    1837             : {
    1838             :         uint32_t ip_instance;
    1839             : 
    1840           0 :         switch (entry->client_id) {
    1841             :         case SOC15_IH_CLIENTID_VCN:
    1842             :                 ip_instance = 0;
    1843             :                 break;
    1844             :         case SOC15_IH_CLIENTID_VCN1:
    1845           0 :                 ip_instance = 1;
    1846           0 :                 break;
    1847             :         default:
    1848           0 :                 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
    1849           0 :                 return 0;
    1850             :         }
    1851             : 
    1852           0 :         DRM_DEBUG("IH: VCN TRAP\n");
    1853             : 
    1854           0 :         switch (entry->src_id) {
    1855             :         case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
    1856           0 :                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
    1857           0 :                 break;
    1858             :         case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
    1859           0 :                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
    1860           0 :                 break;
    1861             :         case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
    1862           0 :                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
    1863           0 :                 break;
    1864             :         case VCN_2_6__SRCID_UVD_POISON:
    1865           0 :                 amdgpu_vcn_process_poison_irq(adev, source, entry);
    1866           0 :                 break;
    1867             :         default:
    1868           0 :                 DRM_ERROR("Unhandled interrupt: %d %d\n",
    1869             :                           entry->src_id, entry->src_data[0]);
    1870           0 :                 break;
    1871             :         }
    1872             : 
    1873             :         return 0;
    1874             : }
    1875             : 
    1876             : static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
    1877             :         .set = vcn_v2_5_set_interrupt_state,
    1878             :         .process = vcn_v2_5_process_interrupt,
    1879             : };
    1880             : 
    1881             : static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
    1882             : {
    1883             :         int i;
    1884             : 
    1885           0 :         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
    1886           0 :                 if (adev->vcn.harvest_config & (1 << i))
    1887           0 :                         continue;
    1888           0 :                 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;
    1889           0 :                 adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
    1890             :         }
    1891             : }
    1892             : 
    1893             : static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
    1894             :         .name = "vcn_v2_5",
    1895             :         .early_init = vcn_v2_5_early_init,
    1896             :         .late_init = NULL,
    1897             :         .sw_init = vcn_v2_5_sw_init,
    1898             :         .sw_fini = vcn_v2_5_sw_fini,
    1899             :         .hw_init = vcn_v2_5_hw_init,
    1900             :         .hw_fini = vcn_v2_5_hw_fini,
    1901             :         .suspend = vcn_v2_5_suspend,
    1902             :         .resume = vcn_v2_5_resume,
    1903             :         .is_idle = vcn_v2_5_is_idle,
    1904             :         .wait_for_idle = vcn_v2_5_wait_for_idle,
    1905             :         .check_soft_reset = NULL,
    1906             :         .pre_soft_reset = NULL,
    1907             :         .soft_reset = NULL,
    1908             :         .post_soft_reset = NULL,
    1909             :         .set_clockgating_state = vcn_v2_5_set_clockgating_state,
    1910             :         .set_powergating_state = vcn_v2_5_set_powergating_state,
    1911             : };
    1912             : 
    1913             : static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
    1914             :         .name = "vcn_v2_6",
    1915             :         .early_init = vcn_v2_5_early_init,
    1916             :         .late_init = NULL,
    1917             :         .sw_init = vcn_v2_5_sw_init,
    1918             :         .sw_fini = vcn_v2_5_sw_fini,
    1919             :         .hw_init = vcn_v2_5_hw_init,
    1920             :         .hw_fini = vcn_v2_5_hw_fini,
    1921             :         .suspend = vcn_v2_5_suspend,
    1922             :         .resume = vcn_v2_5_resume,
    1923             :         .is_idle = vcn_v2_5_is_idle,
    1924             :         .wait_for_idle = vcn_v2_5_wait_for_idle,
    1925             :         .check_soft_reset = NULL,
    1926             :         .pre_soft_reset = NULL,
    1927             :         .soft_reset = NULL,
    1928             :         .post_soft_reset = NULL,
    1929             :         .set_clockgating_state = vcn_v2_5_set_clockgating_state,
    1930             :         .set_powergating_state = vcn_v2_5_set_powergating_state,
    1931             : };
    1932             : 
    1933             : const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
    1934             : {
    1935             :                 .type = AMD_IP_BLOCK_TYPE_VCN,
    1936             :                 .major = 2,
    1937             :                 .minor = 5,
    1938             :                 .rev = 0,
    1939             :                 .funcs = &vcn_v2_5_ip_funcs,
    1940             : };
    1941             : 
    1942             : const struct amdgpu_ip_block_version vcn_v2_6_ip_block =
    1943             : {
    1944             :                 .type = AMD_IP_BLOCK_TYPE_VCN,
    1945             :                 .major = 2,
    1946             :                 .minor = 6,
    1947             :                 .rev = 0,
    1948             :                 .funcs = &vcn_v2_6_ip_funcs,
    1949             : };
    1950             : 
    1951           0 : static uint32_t vcn_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
    1952             :                         uint32_t instance, uint32_t sub_block)
    1953             : {
    1954           0 :         uint32_t poison_stat = 0, reg_value = 0;
    1955             : 
    1956           0 :         switch (sub_block) {
    1957             :         case AMDGPU_VCN_V2_6_VCPU_VCODEC:
    1958           0 :                 reg_value = RREG32_SOC15(VCN, instance, mmUVD_RAS_VCPU_VCODEC_STATUS);
    1959           0 :                 poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
    1960           0 :                 break;
    1961             :         default:
    1962             :                 break;
    1963             :         }
    1964             : 
    1965           0 :         if (poison_stat)
    1966           0 :                 dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
    1967             :                         instance, sub_block);
    1968             : 
    1969           0 :         return poison_stat;
    1970             : }
    1971             : 
    1972           0 : static bool vcn_v2_6_query_poison_status(struct amdgpu_device *adev)
    1973             : {
    1974             :         uint32_t inst, sub;
    1975           0 :         uint32_t poison_stat = 0;
    1976             : 
    1977           0 :         for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
    1978           0 :                 for (sub = 0; sub < AMDGPU_VCN_V2_6_MAX_SUB_BLOCK; sub++)
    1979           0 :                         poison_stat +=
    1980           0 :                         vcn_v2_6_query_poison_by_instance(adev, inst, sub);
    1981             : 
    1982           0 :         return !!poison_stat;
    1983             : }
    1984             : 
    1985             : const struct amdgpu_ras_block_hw_ops vcn_v2_6_ras_hw_ops = {
    1986             :         .query_poison_status = vcn_v2_6_query_poison_status,
    1987             : };
    1988             : 
    1989             : static struct amdgpu_vcn_ras vcn_v2_6_ras = {
    1990             :         .ras_block = {
    1991             :                 .hw_ops = &vcn_v2_6_ras_hw_ops,
    1992             :         },
    1993             : };
    1994             : 
    1995           0 : static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev)
    1996             : {
    1997           0 :         switch (adev->ip_versions[VCN_HWIP][0]) {
    1998             :         case IP_VERSION(2, 6, 0):
    1999           0 :                 adev->vcn.ras = &vcn_v2_6_ras;
    2000           0 :                 break;
    2001             :         default:
    2002             :                 break;
    2003             :         }
    2004             : 
    2005           0 :         if (adev->vcn.ras) {
    2006           0 :                 amdgpu_ras_register_ras_block(adev, &adev->vcn.ras->ras_block);
    2007             : 
    2008           0 :                 strcpy(adev->vcn.ras->ras_block.ras_comm.name, "vcn");
    2009           0 :                 adev->vcn.ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__VCN;
    2010           0 :                 adev->vcn.ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__POISON;
    2011           0 :                 adev->vcn.ras_if = &adev->vcn.ras->ras_block.ras_comm;
    2012             : 
    2013             :                 /* If don't define special ras_late_init function, use default ras_late_init */
    2014           0 :                 if (!adev->vcn.ras->ras_block.ras_late_init)
    2015           0 :                         adev->vcn.ras->ras_block.ras_late_init = amdgpu_ras_block_late_init;
    2016             :         }
    2017           0 : }

Generated by: LCOV version 1.14