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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2016 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  */
      23             : 
      24             : #include <linux/firmware.h>
      25             : 
      26             : #include "amdgpu.h"
      27             : #include "amdgpu_cs.h"
      28             : #include "amdgpu_vcn.h"
      29             : #include "amdgpu_pm.h"
      30             : #include "soc15.h"
      31             : #include "soc15d.h"
      32             : #include "soc15_common.h"
      33             : 
      34             : #include "vcn/vcn_1_0_offset.h"
      35             : #include "vcn/vcn_1_0_sh_mask.h"
      36             : #include "mmhub/mmhub_9_1_offset.h"
      37             : #include "mmhub/mmhub_9_1_sh_mask.h"
      38             : 
      39             : #include "ivsrcid/vcn/irqsrcs_vcn_1_0.h"
      40             : #include "jpeg_v1_0.h"
      41             : #include "vcn_v1_0.h"
      42             : 
      43             : #define mmUVD_RBC_XX_IB_REG_CHECK_1_0           0x05ab
      44             : #define mmUVD_RBC_XX_IB_REG_CHECK_1_0_BASE_IDX  1
      45             : #define mmUVD_REG_XX_MASK_1_0                   0x05ac
      46             : #define mmUVD_REG_XX_MASK_1_0_BASE_IDX          1
      47             : 
      48             : static int vcn_v1_0_stop(struct amdgpu_device *adev);
      49             : static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
      50             : static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev);
      51             : static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev);
      52             : static int vcn_v1_0_set_powergating_state(void *handle, enum amd_powergating_state state);
      53             : static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
      54             :                                 int inst_idx, struct dpg_pause_state *new_state);
      55             : 
      56             : static void vcn_v1_0_idle_work_handler(struct work_struct *work);
      57             : static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring);
      58             : 
      59             : /**
      60             :  * vcn_v1_0_early_init - set function pointers
      61             :  *
      62             :  * @handle: amdgpu_device pointer
      63             :  *
      64             :  * Set ring and irq function pointers
      65             :  */
      66           0 : static int vcn_v1_0_early_init(void *handle)
      67             : {
      68           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
      69             : 
      70           0 :         adev->vcn.num_enc_rings = 2;
      71             : 
      72           0 :         vcn_v1_0_set_dec_ring_funcs(adev);
      73           0 :         vcn_v1_0_set_enc_ring_funcs(adev);
      74           0 :         vcn_v1_0_set_irq_funcs(adev);
      75             : 
      76           0 :         jpeg_v1_0_early_init(handle);
      77             : 
      78           0 :         return 0;
      79             : }
      80             : 
      81             : /**
      82             :  * vcn_v1_0_sw_init - sw init for VCN block
      83             :  *
      84             :  * @handle: amdgpu_device pointer
      85             :  *
      86             :  * Load firmware and sw initialization
      87             :  */
      88           0 : static int vcn_v1_0_sw_init(void *handle)
      89             : {
      90             :         struct amdgpu_ring *ring;
      91             :         int i, r;
      92           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
      93             : 
      94             :         /* VCN DEC TRAP */
      95           0 :         r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
      96             :                         VCN_1_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst->irq);
      97           0 :         if (r)
      98             :                 return r;
      99             : 
     100             :         /* VCN ENC TRAP */
     101           0 :         for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     102           0 :                 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, i + VCN_1_0__SRCID__UVD_ENC_GENERAL_PURPOSE,
     103             :                                         &adev->vcn.inst->irq);
     104           0 :                 if (r)
     105             :                         return r;
     106             :         }
     107             : 
     108           0 :         r = amdgpu_vcn_sw_init(adev);
     109           0 :         if (r)
     110             :                 return r;
     111             : 
     112             :         /* Override the work func */
     113           0 :         adev->vcn.idle_work.work.func = vcn_v1_0_idle_work_handler;
     114             : 
     115           0 :         amdgpu_vcn_setup_ucode(adev);
     116             : 
     117           0 :         r = amdgpu_vcn_resume(adev);
     118           0 :         if (r)
     119             :                 return r;
     120             : 
     121           0 :         ring = &adev->vcn.inst->ring_dec;
     122           0 :         sprintf(ring->name, "vcn_dec");
     123           0 :         r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
     124             :                              AMDGPU_RING_PRIO_DEFAULT, NULL);
     125           0 :         if (r)
     126             :                 return r;
     127             : 
     128           0 :         adev->vcn.internal.scratch9 = adev->vcn.inst->external.scratch9 =
     129           0 :                 SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9);
     130           0 :         adev->vcn.internal.data0 = adev->vcn.inst->external.data0 =
     131           0 :                 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0);
     132           0 :         adev->vcn.internal.data1 = adev->vcn.inst->external.data1 =
     133           0 :                 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1);
     134           0 :         adev->vcn.internal.cmd = adev->vcn.inst->external.cmd =
     135           0 :                 SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD);
     136           0 :         adev->vcn.internal.nop = adev->vcn.inst->external.nop =
     137           0 :                 SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP);
     138             : 
     139           0 :         for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     140           0 :                 enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);
     141             : 
     142           0 :                 ring = &adev->vcn.inst->ring_enc[i];
     143           0 :                 sprintf(ring->name, "vcn_enc%d", i);
     144           0 :                 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst->irq, 0,
     145             :                                      hw_prio, NULL);
     146           0 :                 if (r)
     147             :                         return r;
     148             :         }
     149             : 
     150           0 :         adev->vcn.pause_dpg_mode = vcn_v1_0_pause_dpg_mode;
     151             : 
     152           0 :         if (amdgpu_vcnfw_log) {
     153           0 :                 volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst->fw_shared.cpu_addr;
     154             : 
     155           0 :                 fw_shared->present_flag_0 = 0;
     156           0 :                 amdgpu_vcn_fwlog_init(adev->vcn.inst);
     157             :         }
     158             : 
     159           0 :         r = jpeg_v1_0_sw_init(handle);
     160             : 
     161           0 :         return r;
     162             : }
     163             : 
     164             : /**
     165             :  * vcn_v1_0_sw_fini - sw fini for VCN block
     166             :  *
     167             :  * @handle: amdgpu_device pointer
     168             :  *
     169             :  * VCN suspend and free up sw allocation
     170             :  */
     171           0 : static int vcn_v1_0_sw_fini(void *handle)
     172             : {
     173             :         int r;
     174           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     175             : 
     176           0 :         r = amdgpu_vcn_suspend(adev);
     177           0 :         if (r)
     178             :                 return r;
     179             : 
     180           0 :         jpeg_v1_0_sw_fini(handle);
     181             : 
     182           0 :         r = amdgpu_vcn_sw_fini(adev);
     183             : 
     184           0 :         return r;
     185             : }
     186             : 
     187             : /**
     188             :  * vcn_v1_0_hw_init - start and test VCN block
     189             :  *
     190             :  * @handle: amdgpu_device pointer
     191             :  *
     192             :  * Initialize the hardware, boot up the VCPU and do some testing
     193             :  */
     194           0 : static int vcn_v1_0_hw_init(void *handle)
     195             : {
     196           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     197           0 :         struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
     198             :         int i, r;
     199             : 
     200           0 :         r = amdgpu_ring_test_helper(ring);
     201           0 :         if (r)
     202             :                 goto done;
     203             : 
     204           0 :         for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
     205           0 :                 ring = &adev->vcn.inst->ring_enc[i];
     206           0 :                 r = amdgpu_ring_test_helper(ring);
     207           0 :                 if (r)
     208             :                         goto done;
     209             :         }
     210             : 
     211           0 :         ring = &adev->jpeg.inst->ring_dec;
     212           0 :         r = amdgpu_ring_test_helper(ring);
     213             :         if (r)
     214             :                 goto done;
     215             : 
     216             : done:
     217           0 :         if (!r)
     218           0 :                 DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
     219             :                         (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
     220             : 
     221           0 :         return r;
     222             : }
     223             : 
     224             : /**
     225             :  * vcn_v1_0_hw_fini - stop the hardware block
     226             :  *
     227             :  * @handle: amdgpu_device pointer
     228             :  *
     229             :  * Stop the VCN block, mark ring as not ready any more
     230             :  */
     231           0 : static int vcn_v1_0_hw_fini(void *handle)
     232             : {
     233           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     234             : 
     235           0 :         cancel_delayed_work_sync(&adev->vcn.idle_work);
     236             : 
     237           0 :         if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
     238           0 :                 (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
     239           0 :                  RREG32_SOC15(VCN, 0, mmUVD_STATUS))) {
     240           0 :                 vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
     241             :         }
     242             : 
     243           0 :         return 0;
     244             : }
     245             : 
     246             : /**
     247             :  * vcn_v1_0_suspend - suspend VCN block
     248             :  *
     249             :  * @handle: amdgpu_device pointer
     250             :  *
     251             :  * HW fini and suspend VCN block
     252             :  */
     253           0 : static int vcn_v1_0_suspend(void *handle)
     254             : {
     255             :         int r;
     256           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     257             :         bool idle_work_unexecuted;
     258             : 
     259           0 :         idle_work_unexecuted = cancel_delayed_work_sync(&adev->vcn.idle_work);
     260           0 :         if (idle_work_unexecuted) {
     261           0 :                 if (adev->pm.dpm_enabled)
     262           0 :                         amdgpu_dpm_enable_uvd(adev, false);
     263             :         }
     264             : 
     265           0 :         r = vcn_v1_0_hw_fini(adev);
     266           0 :         if (r)
     267             :                 return r;
     268             : 
     269           0 :         r = amdgpu_vcn_suspend(adev);
     270             : 
     271           0 :         return r;
     272             : }
     273             : 
     274             : /**
     275             :  * vcn_v1_0_resume - resume VCN block
     276             :  *
     277             :  * @handle: amdgpu_device pointer
     278             :  *
     279             :  * Resume firmware and hw init VCN block
     280             :  */
     281           0 : static int vcn_v1_0_resume(void *handle)
     282             : {
     283             :         int r;
     284           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     285             : 
     286           0 :         r = amdgpu_vcn_resume(adev);
     287           0 :         if (r)
     288             :                 return r;
     289             : 
     290           0 :         r = vcn_v1_0_hw_init(adev);
     291             : 
     292           0 :         return r;
     293             : }
     294             : 
     295             : /**
     296             :  * vcn_v1_0_mc_resume_spg_mode - memory controller programming
     297             :  *
     298             :  * @adev: amdgpu_device pointer
     299             :  *
     300             :  * Let the VCN memory controller know it's offsets
     301             :  */
     302           0 : static void vcn_v1_0_mc_resume_spg_mode(struct amdgpu_device *adev)
     303             : {
     304           0 :         uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
     305             :         uint32_t offset;
     306             : 
     307             :         /* cache window 0: fw */
     308           0 :         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
     309           0 :                 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     310             :                              (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
     311           0 :                 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     312             :                              (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
     313           0 :                 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0);
     314             :                 offset = 0;
     315             :         } else {
     316           0 :                 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     317             :                         lower_32_bits(adev->vcn.inst->gpu_addr));
     318           0 :                 WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     319             :                         upper_32_bits(adev->vcn.inst->gpu_addr));
     320           0 :                 offset = size;
     321           0 :                 WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,
     322             :                              AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
     323             :         }
     324             : 
     325           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size);
     326             : 
     327             :         /* cache window 1: stack */
     328           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
     329             :                      lower_32_bits(adev->vcn.inst->gpu_addr + offset));
     330           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
     331             :                      upper_32_bits(adev->vcn.inst->gpu_addr + offset));
     332           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0);
     333           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
     334             : 
     335             :         /* cache window 2: context */
     336           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
     337             :                      lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
     338           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
     339             :                      upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
     340           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0);
     341           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
     342             : 
     343           0 :         WREG32_SOC15(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,
     344             :                         adev->gfx.config.gb_addr_config);
     345           0 :         WREG32_SOC15(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG,
     346             :                         adev->gfx.config.gb_addr_config);
     347           0 :         WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,
     348             :                         adev->gfx.config.gb_addr_config);
     349           0 :         WREG32_SOC15(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,
     350             :                         adev->gfx.config.gb_addr_config);
     351           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,
     352             :                         adev->gfx.config.gb_addr_config);
     353           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,
     354             :                         adev->gfx.config.gb_addr_config);
     355           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,
     356             :                         adev->gfx.config.gb_addr_config);
     357           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,
     358             :                         adev->gfx.config.gb_addr_config);
     359           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,
     360             :                         adev->gfx.config.gb_addr_config);
     361           0 :         WREG32_SOC15(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,
     362             :                         adev->gfx.config.gb_addr_config);
     363           0 :         WREG32_SOC15(UVD, 0, mmUVD_JPEG_ADDR_CONFIG,
     364             :                         adev->gfx.config.gb_addr_config);
     365           0 :         WREG32_SOC15(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG,
     366             :                         adev->gfx.config.gb_addr_config);
     367           0 : }
     368             : 
     369           0 : static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev)
     370             : {
     371           0 :         uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
     372             :         uint32_t offset;
     373             : 
     374             :         /* cache window 0: fw */
     375           0 :         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
     376           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     377             :                              (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo),
     378             :                              0xFFFFFFFF, 0);
     379           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     380             :                              (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi),
     381             :                              0xFFFFFFFF, 0);
     382           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0,
     383             :                              0xFFFFFFFF, 0);
     384             :                 offset = 0;
     385             :         } else {
     386           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     387             :                         lower_32_bits(adev->vcn.inst->gpu_addr), 0xFFFFFFFF, 0);
     388           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     389             :                         upper_32_bits(adev->vcn.inst->gpu_addr), 0xFFFFFFFF, 0);
     390           0 :                 offset = size;
     391           0 :                 WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0,
     392             :                              AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0xFFFFFFFF, 0);
     393             :         }
     394             : 
     395           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size, 0xFFFFFFFF, 0);
     396             : 
     397             :         /* cache window 1: stack */
     398           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
     399             :                      lower_32_bits(adev->vcn.inst->gpu_addr + offset), 0xFFFFFFFF, 0);
     400           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
     401             :                      upper_32_bits(adev->vcn.inst->gpu_addr + offset), 0xFFFFFFFF, 0);
     402           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0,
     403             :                              0xFFFFFFFF, 0);
     404           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE,
     405             :                              0xFFFFFFFF, 0);
     406             : 
     407             :         /* cache window 2: context */
     408           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
     409             :                      lower_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),
     410             :                              0xFFFFFFFF, 0);
     411           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
     412             :                      upper_32_bits(adev->vcn.inst->gpu_addr + offset + AMDGPU_VCN_STACK_SIZE),
     413             :                              0xFFFFFFFF, 0);
     414           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0, 0xFFFFFFFF, 0);
     415           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE,
     416             :                              0xFFFFFFFF, 0);
     417             : 
     418             :         /* VCN global tiling registers */
     419           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_ADDR_CONFIG,
     420             :                         adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     421           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG,
     422             :                         adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     423           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG,
     424             :                         adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     425           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_UDEC_DBW_UV_ADDR_CONFIG,
     426             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     427           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_CURR_ADDR_CONFIG,
     428             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     429           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_CURR_UV_ADDR_CONFIG,
     430             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     431           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_RECON1_ADDR_CONFIG,
     432             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     433           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_RECON1_UV_ADDR_CONFIG,
     434             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     435           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_REF_ADDR_CONFIG,
     436             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     437           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MIF_REF_UV_ADDR_CONFIG,
     438             :                 adev->gfx.config.gb_addr_config, 0xFFFFFFFF, 0);
     439           0 : }
     440             : 
     441             : /**
     442             :  * vcn_v1_0_disable_clock_gating - disable VCN clock gating
     443             :  *
     444             :  * @adev: amdgpu_device pointer
     445             :  *
     446             :  * Disable clock gating for VCN block
     447             :  */
     448           0 : static void vcn_v1_0_disable_clock_gating(struct amdgpu_device *adev)
     449             : {
     450             :         uint32_t data;
     451             : 
     452             :         /* JPEG disable CGC */
     453           0 :         data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
     454             : 
     455           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     456           0 :                 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     457             :         else
     458           0 :                 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE_MASK;
     459             : 
     460           0 :         data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     461           0 :         data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     462           0 :         WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, data);
     463             : 
     464           0 :         data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);
     465           0 :         data &= ~(JPEG_CGC_GATE__JPEG_MASK | JPEG_CGC_GATE__JPEG2_MASK);
     466           0 :         WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, data);
     467             : 
     468             :         /* UVD disable CGC */
     469           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
     470           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     471           0 :                 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     472             :         else
     473           0 :                 data &= ~ UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
     474             : 
     475           0 :         data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     476           0 :         data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     477           0 :         WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
     478             : 
     479           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_CGC_GATE);
     480           0 :         data &= ~(UVD_CGC_GATE__SYS_MASK
     481             :                 | UVD_CGC_GATE__UDEC_MASK
     482             :                 | UVD_CGC_GATE__MPEG2_MASK
     483             :                 | UVD_CGC_GATE__REGS_MASK
     484             :                 | UVD_CGC_GATE__RBC_MASK
     485             :                 | UVD_CGC_GATE__LMI_MC_MASK
     486             :                 | UVD_CGC_GATE__LMI_UMC_MASK
     487             :                 | UVD_CGC_GATE__IDCT_MASK
     488             :                 | UVD_CGC_GATE__MPRD_MASK
     489             :                 | UVD_CGC_GATE__MPC_MASK
     490             :                 | UVD_CGC_GATE__LBSI_MASK
     491             :                 | UVD_CGC_GATE__LRBBM_MASK
     492             :                 | UVD_CGC_GATE__UDEC_RE_MASK
     493             :                 | UVD_CGC_GATE__UDEC_CM_MASK
     494             :                 | UVD_CGC_GATE__UDEC_IT_MASK
     495             :                 | UVD_CGC_GATE__UDEC_DB_MASK
     496             :                 | UVD_CGC_GATE__UDEC_MP_MASK
     497             :                 | UVD_CGC_GATE__WCB_MASK
     498             :                 | UVD_CGC_GATE__VCPU_MASK
     499             :                 | UVD_CGC_GATE__SCPU_MASK);
     500           0 :         WREG32_SOC15(VCN, 0, mmUVD_CGC_GATE, data);
     501             : 
     502           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
     503           0 :         data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
     504             :                 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
     505             :                 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
     506             :                 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
     507             :                 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
     508             :                 | UVD_CGC_CTRL__SYS_MODE_MASK
     509             :                 | UVD_CGC_CTRL__UDEC_MODE_MASK
     510             :                 | UVD_CGC_CTRL__MPEG2_MODE_MASK
     511             :                 | UVD_CGC_CTRL__REGS_MODE_MASK
     512             :                 | UVD_CGC_CTRL__RBC_MODE_MASK
     513             :                 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
     514             :                 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
     515             :                 | UVD_CGC_CTRL__IDCT_MODE_MASK
     516             :                 | UVD_CGC_CTRL__MPRD_MODE_MASK
     517             :                 | UVD_CGC_CTRL__MPC_MODE_MASK
     518             :                 | UVD_CGC_CTRL__LBSI_MODE_MASK
     519             :                 | UVD_CGC_CTRL__LRBBM_MODE_MASK
     520             :                 | UVD_CGC_CTRL__WCB_MODE_MASK
     521             :                 | UVD_CGC_CTRL__VCPU_MODE_MASK
     522             :                 | UVD_CGC_CTRL__SCPU_MODE_MASK);
     523           0 :         WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
     524             : 
     525             :         /* turn on */
     526           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE);
     527           0 :         data |= (UVD_SUVD_CGC_GATE__SRE_MASK
     528             :                 | UVD_SUVD_CGC_GATE__SIT_MASK
     529             :                 | UVD_SUVD_CGC_GATE__SMP_MASK
     530             :                 | UVD_SUVD_CGC_GATE__SCM_MASK
     531             :                 | UVD_SUVD_CGC_GATE__SDB_MASK
     532             :                 | UVD_SUVD_CGC_GATE__SRE_H264_MASK
     533             :                 | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
     534             :                 | UVD_SUVD_CGC_GATE__SIT_H264_MASK
     535             :                 | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
     536             :                 | UVD_SUVD_CGC_GATE__SCM_H264_MASK
     537             :                 | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
     538             :                 | UVD_SUVD_CGC_GATE__SDB_H264_MASK
     539             :                 | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
     540             :                 | UVD_SUVD_CGC_GATE__SCLR_MASK
     541             :                 | UVD_SUVD_CGC_GATE__UVD_SC_MASK
     542             :                 | UVD_SUVD_CGC_GATE__ENT_MASK
     543             :                 | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
     544             :                 | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
     545             :                 | UVD_SUVD_CGC_GATE__SITE_MASK
     546             :                 | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
     547             :                 | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
     548             :                 | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
     549             :                 | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
     550             :                 | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
     551           0 :         WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_GATE, data);
     552             : 
     553           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);
     554           0 :         data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
     555             :                 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
     556             :                 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
     557             :                 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
     558             :                 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
     559             :                 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
     560             :                 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
     561             :                 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
     562             :                 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
     563             :                 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
     564           0 :         WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
     565           0 : }
     566             : 
     567             : /**
     568             :  * vcn_v1_0_enable_clock_gating - enable VCN clock gating
     569             :  *
     570             :  * @adev: amdgpu_device pointer
     571             :  *
     572             :  * Enable clock gating for VCN block
     573             :  */
     574           0 : static void vcn_v1_0_enable_clock_gating(struct amdgpu_device *adev)
     575             : {
     576           0 :         uint32_t data = 0;
     577             : 
     578             :         /* enable JPEG CGC */
     579           0 :         data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL);
     580           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     581           0 :                 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     582             :         else
     583             :                 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     584           0 :         data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     585           0 :         data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     586           0 :         WREG32_SOC15(VCN, 0, mmJPEG_CGC_CTRL, data);
     587             : 
     588           0 :         data = RREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE);
     589           0 :         data |= (JPEG_CGC_GATE__JPEG_MASK | JPEG_CGC_GATE__JPEG2_MASK);
     590           0 :         WREG32_SOC15(VCN, 0, mmJPEG_CGC_GATE, data);
     591             : 
     592             :         /* enable UVD CGC */
     593           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
     594           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     595           0 :                 data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     596             :         else
     597             :                 data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     598           0 :         data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     599           0 :         data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     600           0 :         WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
     601             : 
     602           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL);
     603           0 :         data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
     604             :                 | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
     605             :                 | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
     606             :                 | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
     607             :                 | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
     608             :                 | UVD_CGC_CTRL__SYS_MODE_MASK
     609             :                 | UVD_CGC_CTRL__UDEC_MODE_MASK
     610             :                 | UVD_CGC_CTRL__MPEG2_MODE_MASK
     611             :                 | UVD_CGC_CTRL__REGS_MODE_MASK
     612             :                 | UVD_CGC_CTRL__RBC_MODE_MASK
     613             :                 | UVD_CGC_CTRL__LMI_MC_MODE_MASK
     614             :                 | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
     615             :                 | UVD_CGC_CTRL__IDCT_MODE_MASK
     616             :                 | UVD_CGC_CTRL__MPRD_MODE_MASK
     617             :                 | UVD_CGC_CTRL__MPC_MODE_MASK
     618             :                 | UVD_CGC_CTRL__LBSI_MODE_MASK
     619             :                 | UVD_CGC_CTRL__LRBBM_MODE_MASK
     620             :                 | UVD_CGC_CTRL__WCB_MODE_MASK
     621             :                 | UVD_CGC_CTRL__VCPU_MODE_MASK
     622             :                 | UVD_CGC_CTRL__SCPU_MODE_MASK);
     623           0 :         WREG32_SOC15(VCN, 0, mmUVD_CGC_CTRL, data);
     624             : 
     625           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL);
     626           0 :         data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
     627             :                 | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
     628             :                 | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
     629             :                 | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
     630             :                 | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
     631             :                 | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
     632             :                 | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
     633             :                 | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
     634             :                 | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
     635             :                 | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
     636           0 :         WREG32_SOC15(VCN, 0, mmUVD_SUVD_CGC_CTRL, data);
     637           0 : }
     638             : 
     639           0 : static void vcn_v1_0_clock_gating_dpg_mode(struct amdgpu_device *adev, uint8_t sram_sel)
     640             : {
     641           0 :         uint32_t reg_data = 0;
     642             : 
     643             :         /* disable JPEG CGC */
     644           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     645             :                 reg_data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     646             :         else
     647           0 :                 reg_data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     648           0 :         reg_data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     649           0 :         reg_data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     650           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmJPEG_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);
     651             : 
     652           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmJPEG_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);
     653             : 
     654             :         /* enable sw clock gating control */
     655           0 :         if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
     656             :                 reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     657             :         else
     658           0 :                 reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
     659           0 :         reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
     660           0 :         reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
     661           0 :         reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
     662             :                  UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
     663             :                  UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
     664             :                  UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
     665             :                  UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
     666             :                  UVD_CGC_CTRL__SYS_MODE_MASK |
     667             :                  UVD_CGC_CTRL__UDEC_MODE_MASK |
     668             :                  UVD_CGC_CTRL__MPEG2_MODE_MASK |
     669             :                  UVD_CGC_CTRL__REGS_MODE_MASK |
     670             :                  UVD_CGC_CTRL__RBC_MODE_MASK |
     671             :                  UVD_CGC_CTRL__LMI_MC_MODE_MASK |
     672             :                  UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
     673             :                  UVD_CGC_CTRL__IDCT_MODE_MASK |
     674             :                  UVD_CGC_CTRL__MPRD_MODE_MASK |
     675             :                  UVD_CGC_CTRL__MPC_MODE_MASK |
     676             :                  UVD_CGC_CTRL__LBSI_MODE_MASK |
     677             :                  UVD_CGC_CTRL__LRBBM_MODE_MASK |
     678             :                  UVD_CGC_CTRL__WCB_MODE_MASK |
     679             :                  UVD_CGC_CTRL__VCPU_MODE_MASK |
     680             :                  UVD_CGC_CTRL__SCPU_MODE_MASK);
     681           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_CGC_CTRL, reg_data, 0xFFFFFFFF, sram_sel);
     682             : 
     683             :         /* turn off clock gating */
     684           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_CGC_GATE, 0, 0xFFFFFFFF, sram_sel);
     685             : 
     686             :         /* turn on SUVD clock gating */
     687           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SUVD_CGC_GATE, 1, 0xFFFFFFFF, sram_sel);
     688             : 
     689             :         /* turn on sw mode in UVD_SUVD_CGC_CTRL */
     690           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SUVD_CGC_CTRL, 0, 0xFFFFFFFF, sram_sel);
     691           0 : }
     692             : 
     693           0 : static void vcn_1_0_disable_static_power_gating(struct amdgpu_device *adev)
     694             : {
     695           0 :         uint32_t data = 0;
     696             : 
     697           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
     698           0 :                 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
     699             :                         | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
     700             :                         | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
     701             :                         | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
     702             :                         | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
     703             :                         | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
     704             :                         | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
     705             :                         | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
     706             :                         | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
     707             :                         | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
     708             :                         | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
     709             : 
     710           0 :                 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
     711           0 :                 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS__UVDM_UVDU_PWR_ON, 0xFFFFFF);
     712             :         } else {
     713           0 :                 data = (1 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
     714             :                         | 1 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
     715             :                         | 1 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
     716             :                         | 1 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
     717             :                         | 1 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
     718             :                         | 1 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
     719             :                         | 1 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
     720             :                         | 1 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
     721             :                         | 1 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
     722             :                         | 1 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
     723             :                         | 1 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
     724           0 :                 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
     725           0 :                 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, 0,  0xFFFFFFFF);
     726             :         }
     727             : 
     728             :         /* polling UVD_PGFSM_STATUS to confirm UVDM_PWR_STATUS , UVDU_PWR_STATUS are 0 (power on) */
     729             : 
     730           0 :         data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
     731           0 :         data &= ~0x103;
     732           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN)
     733           0 :                 data |= UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON | UVD_POWER_STATUS__UVD_PG_EN_MASK;
     734             : 
     735           0 :         WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
     736           0 : }
     737             : 
     738           0 : static void vcn_1_0_enable_static_power_gating(struct amdgpu_device *adev)
     739             : {
     740           0 :         uint32_t data = 0;
     741             : 
     742           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN) {
     743             :                 /* Before power off, this indicator has to be turned on */
     744           0 :                 data = RREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS);
     745           0 :                 data &= ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK;
     746           0 :                 data |= UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF;
     747           0 :                 WREG32_SOC15(VCN, 0, mmUVD_POWER_STATUS, data);
     748             : 
     749             : 
     750           0 :                 data = (2 << UVD_PGFSM_CONFIG__UVDM_PWR_CONFIG__SHIFT
     751             :                         | 2 << UVD_PGFSM_CONFIG__UVDU_PWR_CONFIG__SHIFT
     752             :                         | 2 << UVD_PGFSM_CONFIG__UVDF_PWR_CONFIG__SHIFT
     753             :                         | 2 << UVD_PGFSM_CONFIG__UVDC_PWR_CONFIG__SHIFT
     754             :                         | 2 << UVD_PGFSM_CONFIG__UVDB_PWR_CONFIG__SHIFT
     755             :                         | 2 << UVD_PGFSM_CONFIG__UVDIL_PWR_CONFIG__SHIFT
     756             :                         | 2 << UVD_PGFSM_CONFIG__UVDIR_PWR_CONFIG__SHIFT
     757             :                         | 2 << UVD_PGFSM_CONFIG__UVDTD_PWR_CONFIG__SHIFT
     758             :                         | 2 << UVD_PGFSM_CONFIG__UVDTE_PWR_CONFIG__SHIFT
     759             :                         | 2 << UVD_PGFSM_CONFIG__UVDE_PWR_CONFIG__SHIFT
     760             :                         | 2 << UVD_PGFSM_CONFIG__UVDW_PWR_CONFIG__SHIFT);
     761             : 
     762           0 :                 WREG32_SOC15(VCN, 0, mmUVD_PGFSM_CONFIG, data);
     763             : 
     764           0 :                 data = (2 << UVD_PGFSM_STATUS__UVDM_PWR_STATUS__SHIFT
     765             :                         | 2 << UVD_PGFSM_STATUS__UVDU_PWR_STATUS__SHIFT
     766             :                         | 2 << UVD_PGFSM_STATUS__UVDF_PWR_STATUS__SHIFT
     767             :                         | 2 << UVD_PGFSM_STATUS__UVDC_PWR_STATUS__SHIFT
     768             :                         | 2 << UVD_PGFSM_STATUS__UVDB_PWR_STATUS__SHIFT
     769             :                         | 2 << UVD_PGFSM_STATUS__UVDIL_PWR_STATUS__SHIFT
     770             :                         | 2 << UVD_PGFSM_STATUS__UVDIR_PWR_STATUS__SHIFT
     771             :                         | 2 << UVD_PGFSM_STATUS__UVDTD_PWR_STATUS__SHIFT
     772             :                         | 2 << UVD_PGFSM_STATUS__UVDTE_PWR_STATUS__SHIFT
     773             :                         | 2 << UVD_PGFSM_STATUS__UVDE_PWR_STATUS__SHIFT
     774             :                         | 2 << UVD_PGFSM_STATUS__UVDW_PWR_STATUS__SHIFT);
     775           0 :                 SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_PGFSM_STATUS, data, 0xFFFFFFFF);
     776             :         }
     777           0 : }
     778             : 
     779             : /**
     780             :  * vcn_v1_0_start_spg_mode - start VCN block
     781             :  *
     782             :  * @adev: amdgpu_device pointer
     783             :  *
     784             :  * Setup and start the VCN block
     785             :  */
     786           0 : static int vcn_v1_0_start_spg_mode(struct amdgpu_device *adev)
     787             : {
     788           0 :         struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
     789             :         uint32_t rb_bufsz, tmp;
     790             :         uint32_t lmi_swap_cntl;
     791             :         int i, j, r;
     792             : 
     793             :         /* disable byte swapping */
     794           0 :         lmi_swap_cntl = 0;
     795             : 
     796           0 :         vcn_1_0_disable_static_power_gating(adev);
     797             : 
     798           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
     799           0 :         WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);
     800             : 
     801             :         /* disable clock gating */
     802           0 :         vcn_v1_0_disable_clock_gating(adev);
     803             : 
     804             :         /* disable interupt */
     805           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN), 0,
     806             :                         ~UVD_MASTINT_EN__VCPU_EN_MASK);
     807             : 
     808             :         /* initialize VCN memory controller */
     809           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL);
     810           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_CTRL, tmp                |
     811             :                 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
     812             :                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK                       |
     813             :                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK            |
     814             :                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
     815             : 
     816             : #ifdef __BIG_ENDIAN
     817             :         /* swap (8 in 32) RB and IB */
     818             :         lmi_swap_cntl = 0xa;
     819             : #endif
     820           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
     821             : 
     822           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL);
     823           0 :         tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
     824           0 :         tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
     825           0 :         WREG32_SOC15(UVD, 0, mmUVD_MPC_CNTL, tmp);
     826             : 
     827           0 :         WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXA0,
     828             :                 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
     829             :                 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
     830             :                 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
     831             :                 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
     832             : 
     833           0 :         WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUXB0,
     834             :                 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
     835             :                 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
     836             :                 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
     837             :                 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
     838             : 
     839           0 :         WREG32_SOC15(UVD, 0, mmUVD_MPC_SET_MUX,
     840             :                 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
     841             :                 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
     842             :                 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
     843             : 
     844           0 :         vcn_v1_0_mc_resume_spg_mode(adev);
     845             : 
     846           0 :         WREG32_SOC15(UVD, 0, mmUVD_REG_XX_MASK_1_0, 0x10);
     847           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0,
     848             :                 RREG32_SOC15(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK_1_0) | 0x3);
     849             : 
     850             :         /* enable VCPU clock */
     851           0 :         WREG32_SOC15(UVD, 0, mmUVD_VCPU_CNTL, UVD_VCPU_CNTL__CLK_EN_MASK);
     852             : 
     853             :         /* boot up the VCPU */
     854           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
     855             :                         ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     856             : 
     857             :         /* enable UMC */
     858           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2), 0,
     859             :                         ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
     860             : 
     861           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET);
     862           0 :         tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
     863           0 :         tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
     864           0 :         WREG32_SOC15(UVD, 0, mmUVD_SOFT_RESET, tmp);
     865             : 
     866           0 :         for (i = 0; i < 10; ++i) {
     867             :                 uint32_t status;
     868             : 
     869           0 :                 for (j = 0; j < 100; ++j) {
     870           0 :                         status = RREG32_SOC15(UVD, 0, mmUVD_STATUS);
     871           0 :                         if (status & UVD_STATUS__IDLE)
     872             :                                 break;
     873           0 :                         mdelay(10);
     874             :                 }
     875           0 :                 r = 0;
     876           0 :                 if (status & UVD_STATUS__IDLE)
     877             :                         break;
     878             : 
     879           0 :                 DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
     880           0 :                 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
     881             :                                 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
     882             :                                 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     883           0 :                 mdelay(10);
     884           0 :                 WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET), 0,
     885             :                                 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     886           0 :                 mdelay(10);
     887           0 :                 r = -1;
     888             :         }
     889             : 
     890           0 :         if (r) {
     891           0 :                 DRM_ERROR("VCN decode not responding, giving up!!!\n");
     892           0 :                 return r;
     893             :         }
     894             :         /* enable master interrupt */
     895           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_MASTINT_EN),
     896             :                 UVD_MASTINT_EN__VCPU_EN_MASK, ~UVD_MASTINT_EN__VCPU_EN_MASK);
     897             : 
     898             :         /* enable system interrupt for JRBC, TODO: move to set interrupt*/
     899           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SYS_INT_EN),
     900             :                 UVD_SYS_INT_EN__UVD_JRBC_EN_MASK,
     901             :                 ~UVD_SYS_INT_EN__UVD_JRBC_EN_MASK);
     902             : 
     903             :         /* clear the busy bit of UVD_STATUS */
     904           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_STATUS) & ~UVD_STATUS__UVD_BUSY;
     905           0 :         WREG32_SOC15(UVD, 0, mmUVD_STATUS, tmp);
     906             : 
     907             :         /* force RBC into idle state */
     908           0 :         rb_bufsz = order_base_2(ring->ring_size);
     909           0 :         tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
     910           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
     911           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
     912           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
     913           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
     914           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
     915             : 
     916             :         /* set the write pointer delay */
     917           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);
     918             : 
     919             :         /* set the wb address */
     920           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,
     921             :                         (upper_32_bits(ring->gpu_addr) >> 2));
     922             : 
     923             :         /* program the RB_BASE for ring buffer */
     924           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
     925             :                         lower_32_bits(ring->gpu_addr));
     926           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
     927             :                         upper_32_bits(ring->gpu_addr));
     928             : 
     929             :         /* Initialize the ring buffer's read and write pointers */
     930           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
     931             : 
     932           0 :         WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);
     933             : 
     934           0 :         ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
     935           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
     936             :                         lower_32_bits(ring->wptr));
     937             : 
     938           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,
     939             :                         ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
     940             : 
     941           0 :         ring = &adev->vcn.inst->ring_enc[0];
     942           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
     943           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
     944           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
     945           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
     946           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
     947             : 
     948           0 :         ring = &adev->vcn.inst->ring_enc[1];
     949           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
     950           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
     951           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
     952           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
     953           0 :         WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
     954             : 
     955           0 :         jpeg_v1_0_start(adev, 0);
     956             : 
     957           0 :         return 0;
     958             : }
     959             : 
     960           0 : static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev)
     961             : {
     962           0 :         struct amdgpu_ring *ring = &adev->vcn.inst->ring_dec;
     963             :         uint32_t rb_bufsz, tmp;
     964             :         uint32_t lmi_swap_cntl;
     965             : 
     966             :         /* disable byte swapping */
     967           0 :         lmi_swap_cntl = 0;
     968             : 
     969           0 :         vcn_1_0_enable_static_power_gating(adev);
     970             : 
     971             :         /* enable dynamic power gating mode */
     972           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
     973           0 :         tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
     974           0 :         tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
     975           0 :         WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, tmp);
     976             : 
     977             :         /* enable clock gating */
     978           0 :         vcn_v1_0_clock_gating_dpg_mode(adev, 0);
     979             : 
     980             :         /* enable VCPU clock */
     981           0 :         tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
     982           0 :         tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
     983           0 :         tmp |= UVD_VCPU_CNTL__MIF_WR_LOW_THRESHOLD_BP_MASK;
     984           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_VCPU_CNTL, tmp, 0xFFFFFFFF, 0);
     985             : 
     986             :         /* disable interupt */
     987           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MASTINT_EN,
     988             :                         0, UVD_MASTINT_EN__VCPU_EN_MASK, 0);
     989             : 
     990             :         /* initialize VCN memory controller */
     991           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL,
     992             :                 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
     993             :                 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
     994             :                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
     995             :                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
     996             :                 UVD_LMI_CTRL__REQ_MODE_MASK |
     997             :                 UVD_LMI_CTRL__CRC_RESET_MASK |
     998             :                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
     999             :                 0x00100000L, 0xFFFFFFFF, 0);
    1000             : 
    1001             : #ifdef __BIG_ENDIAN
    1002             :         /* swap (8 in 32) RB and IB */
    1003             :         lmi_swap_cntl = 0xa;
    1004             : #endif
    1005           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl, 0xFFFFFFFF, 0);
    1006             : 
    1007           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_CNTL,
    1008             :                 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0xFFFFFFFF, 0);
    1009             : 
    1010           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUXA0,
    1011             :                 ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
    1012             :                  (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
    1013             :                  (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
    1014             :                  (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0xFFFFFFFF, 0);
    1015             : 
    1016           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUXB0,
    1017             :                 ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
    1018             :                  (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
    1019             :                  (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
    1020             :                  (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0xFFFFFFFF, 0);
    1021             : 
    1022           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MPC_SET_MUX,
    1023             :                 ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
    1024             :                  (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
    1025             :                  (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0xFFFFFFFF, 0);
    1026             : 
    1027           0 :         vcn_v1_0_mc_resume_dpg_mode(adev);
    1028             : 
    1029           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_REG_XX_MASK, 0x10, 0xFFFFFFFF, 0);
    1030           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK, 0x3, 0xFFFFFFFF, 0);
    1031             : 
    1032             :         /* boot up the VCPU */
    1033           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SOFT_RESET, 0, 0xFFFFFFFF, 0);
    1034             : 
    1035             :         /* enable UMC */
    1036           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL2,
    1037             :                 0x1F << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT,
    1038             :                 0xFFFFFFFF, 0);
    1039             : 
    1040             :         /* enable master interrupt */
    1041           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_MASTINT_EN,
    1042             :                         UVD_MASTINT_EN__VCPU_EN_MASK, UVD_MASTINT_EN__VCPU_EN_MASK, 0);
    1043             : 
    1044           0 :         vcn_v1_0_clock_gating_dpg_mode(adev, 1);
    1045             :         /* setup mmUVD_LMI_CTRL */
    1046           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_LMI_CTRL,
    1047             :                 (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
    1048             :                 UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
    1049             :                 UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
    1050             :                 UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
    1051             :                 UVD_LMI_CTRL__REQ_MODE_MASK |
    1052             :                 UVD_LMI_CTRL__CRC_RESET_MASK |
    1053             :                 UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
    1054             :                 0x00100000L, 0xFFFFFFFF, 1);
    1055             : 
    1056           0 :         tmp = adev->gfx.config.gb_addr_config;
    1057             :         /* setup VCN global tiling registers */
    1058           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);
    1059           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, tmp, 0xFFFFFFFF, 1);
    1060             : 
    1061             :         /* enable System Interrupt for JRBC */
    1062           0 :         WREG32_SOC15_DPG_MODE_1_0(UVD, 0, mmUVD_SYS_INT_EN,
    1063             :                                                                         UVD_SYS_INT_EN__UVD_JRBC_EN_MASK, 0xFFFFFFFF, 1);
    1064             : 
    1065             :         /* force RBC into idle state */
    1066           0 :         rb_bufsz = order_base_2(ring->ring_size);
    1067           0 :         tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
    1068           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
    1069           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
    1070           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
    1071           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
    1072           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_CNTL, tmp);
    1073             : 
    1074             :         /* set the write pointer delay */
    1075           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR_CNTL, 0);
    1076             : 
    1077             :         /* set the wb address */
    1078           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR_ADDR,
    1079             :                                                                 (upper_32_bits(ring->gpu_addr) >> 2));
    1080             : 
    1081             :         /* program the RB_BASE for ring buffer */
    1082           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
    1083             :                                                                 lower_32_bits(ring->gpu_addr));
    1084           0 :         WREG32_SOC15(UVD, 0, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
    1085             :                                                                 upper_32_bits(ring->gpu_addr));
    1086             : 
    1087             :         /* Initialize the ring buffer's read and write pointers */
    1088           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR, 0);
    1089             : 
    1090           0 :         WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2, 0);
    1091             : 
    1092           0 :         ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
    1093           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
    1094             :                                                                 lower_32_bits(ring->wptr));
    1095             : 
    1096           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,
    1097             :                         ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
    1098             : 
    1099           0 :         jpeg_v1_0_start(adev, 1);
    1100             : 
    1101           0 :         return 0;
    1102             : }
    1103             : 
    1104           0 : static int vcn_v1_0_start(struct amdgpu_device *adev)
    1105             : {
    1106           0 :         return (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ?
    1107           0 :                 vcn_v1_0_start_dpg_mode(adev) : vcn_v1_0_start_spg_mode(adev);
    1108             : }
    1109             : 
    1110             : /**
    1111             :  * vcn_v1_0_stop_spg_mode - stop VCN block
    1112             :  *
    1113             :  * @adev: amdgpu_device pointer
    1114             :  *
    1115             :  * stop the VCN block
    1116             :  */
    1117           0 : static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev)
    1118             : {
    1119             :         int tmp;
    1120             : 
    1121           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
    1122             : 
    1123           0 :         tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
    1124             :                 UVD_LMI_STATUS__READ_CLEAN_MASK |
    1125             :                 UVD_LMI_STATUS__WRITE_CLEAN_MASK |
    1126             :                 UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
    1127           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp);
    1128             : 
    1129             :         /* stall UMC channel */
    1130           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_CTRL2),
    1131             :                 UVD_LMI_CTRL2__STALL_ARB_UMC_MASK,
    1132             :                 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
    1133             : 
    1134           0 :         tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
    1135             :                 UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
    1136           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_LMI_STATUS, tmp, tmp);
    1137             : 
    1138             :         /* disable VCPU clock */
    1139           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_VCPU_CNTL), 0,
    1140             :                 ~UVD_VCPU_CNTL__CLK_EN_MASK);
    1141             : 
    1142             :         /* reset LMI UMC/LMI */
    1143           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
    1144             :                 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK,
    1145             :                 ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
    1146             : 
    1147           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
    1148             :                 UVD_SOFT_RESET__LMI_SOFT_RESET_MASK,
    1149             :                 ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK);
    1150             : 
    1151             :         /* put VCPU into reset */
    1152           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_SOFT_RESET),
    1153             :                 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
    1154             :                 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
    1155             : 
    1156           0 :         WREG32_SOC15(UVD, 0, mmUVD_STATUS, 0);
    1157             : 
    1158           0 :         vcn_v1_0_enable_clock_gating(adev);
    1159           0 :         vcn_1_0_enable_static_power_gating(adev);
    1160           0 :         return 0;
    1161             : }
    1162             : 
    1163           0 : static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev)
    1164             : {
    1165             :         uint32_t tmp;
    1166             : 
    1167             :         /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */
    1168           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1169             :                         UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
    1170             :                         UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1171             : 
    1172             :         /* wait for read ptr to be equal to write ptr */
    1173           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);
    1174           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
    1175             : 
    1176           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);
    1177           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
    1178             : 
    1179           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
    1180           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_JRBC_RB_RPTR, tmp, 0xFFFFFFFF);
    1181             : 
    1182           0 :         tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
    1183           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
    1184             : 
    1185           0 :         SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1186             :                 UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
    1187             :                 UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1188             : 
    1189             :         /* disable dynamic power gating mode */
    1190           0 :         WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0,
    1191             :                         ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
    1192             : 
    1193           0 :         return 0;
    1194             : }
    1195             : 
    1196           0 : static int vcn_v1_0_stop(struct amdgpu_device *adev)
    1197             : {
    1198             :         int r;
    1199             : 
    1200           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
    1201           0 :                 r = vcn_v1_0_stop_dpg_mode(adev);
    1202             :         else
    1203           0 :                 r = vcn_v1_0_stop_spg_mode(adev);
    1204             : 
    1205           0 :         return r;
    1206             : }
    1207             : 
    1208           0 : static int vcn_v1_0_pause_dpg_mode(struct amdgpu_device *adev,
    1209             :                                 int inst_idx, struct dpg_pause_state *new_state)
    1210             : {
    1211             :         int ret_code;
    1212           0 :         uint32_t reg_data = 0;
    1213           0 :         uint32_t reg_data2 = 0;
    1214             :         struct amdgpu_ring *ring;
    1215             : 
    1216             :         /* pause/unpause if state is changed */
    1217           0 :         if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
    1218           0 :                 DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
    1219             :                         adev->vcn.inst[inst_idx].pause_state.fw_based,
    1220             :                         adev->vcn.inst[inst_idx].pause_state.jpeg,
    1221             :                         new_state->fw_based, new_state->jpeg);
    1222             : 
    1223           0 :                 reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
    1224             :                         (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
    1225             : 
    1226           0 :                 if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
    1227           0 :                         ret_code = 0;
    1228             : 
    1229           0 :                         if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK))
    1230           0 :                                 ret_code = SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1231             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
    1232             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1233             : 
    1234           0 :                         if (!ret_code) {
    1235             :                                 /* pause DPG non-jpeg */
    1236           0 :                                 reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
    1237           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
    1238           0 :                                 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
    1239             :                                                    UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
    1240             :                                                    UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
    1241             : 
    1242             :                                 /* Restore */
    1243           0 :                                 ring = &adev->vcn.inst->ring_enc[0];
    1244           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr);
    1245           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
    1246           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4);
    1247           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
    1248           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
    1249             : 
    1250           0 :                                 ring = &adev->vcn.inst->ring_enc[1];
    1251           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr);
    1252           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
    1253           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4);
    1254           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
    1255           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
    1256             : 
    1257           0 :                                 ring = &adev->vcn.inst->ring_dec;
    1258           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
    1259             :                                                    RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
    1260           0 :                                 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1261             :                                                    UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
    1262             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1263             :                         }
    1264             :                 } else {
    1265             :                         /* unpause dpg non-jpeg, no need to wait */
    1266           0 :                         reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
    1267           0 :                         WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
    1268             :                 }
    1269           0 :                 adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
    1270             :         }
    1271             : 
    1272             :         /* pause/unpause if state is changed */
    1273           0 :         if (adev->vcn.inst[inst_idx].pause_state.jpeg != new_state->jpeg) {
    1274           0 :                 DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d",
    1275             :                         adev->vcn.inst[inst_idx].pause_state.fw_based,
    1276             :                         adev->vcn.inst[inst_idx].pause_state.jpeg,
    1277             :                         new_state->fw_based, new_state->jpeg);
    1278             : 
    1279           0 :                 reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) &
    1280             :                         (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
    1281             : 
    1282           0 :                 if (new_state->jpeg == VCN_DPG_STATE__PAUSE) {
    1283           0 :                         ret_code = 0;
    1284             : 
    1285           0 :                         if (!(reg_data & UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK))
    1286           0 :                                 ret_code = SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1287             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
    1288             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1289             : 
    1290           0 :                         if (!ret_code) {
    1291             :                                 /* Make sure JPRG Snoop is disabled before sending the pause */
    1292           0 :                                 reg_data2 = RREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS);
    1293           0 :                                 reg_data2 |= UVD_POWER_STATUS__JRBC_SNOOP_DIS_MASK;
    1294           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_POWER_STATUS, reg_data2);
    1295             : 
    1296             :                                 /* pause DPG jpeg */
    1297           0 :                                 reg_data |= UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
    1298           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
    1299           0 :                                 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE,
    1300             :                                                         UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK,
    1301             :                                                         UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK);
    1302             : 
    1303             :                                 /* Restore */
    1304           0 :                                 ring = &adev->jpeg.inst->ring_dec;
    1305           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
    1306           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
    1307             :                                                         UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
    1308             :                                                         UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
    1309           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
    1310             :                                                         lower_32_bits(ring->gpu_addr));
    1311           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
    1312             :                                                         upper_32_bits(ring->gpu_addr));
    1313           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_RPTR, ring->wptr);
    1314           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR, ring->wptr);
    1315           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_CNTL,
    1316             :                                                         UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
    1317             : 
    1318           0 :                                 ring = &adev->vcn.inst->ring_dec;
    1319           0 :                                 WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR,
    1320             :                                                    RREG32_SOC15(UVD, 0, mmUVD_SCRATCH2) & 0x7FFFFFFF);
    1321           0 :                                 SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
    1322             :                                                    UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON,
    1323             :                                                    UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
    1324             :                         }
    1325             :                 } else {
    1326             :                         /* unpause dpg jpeg, no need to wait */
    1327           0 :                         reg_data &= ~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK;
    1328           0 :                         WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data);
    1329             :                 }
    1330           0 :                 adev->vcn.inst[inst_idx].pause_state.jpeg = new_state->jpeg;
    1331             :         }
    1332             : 
    1333           0 :         return 0;
    1334             : }
    1335             : 
    1336           0 : static bool vcn_v1_0_is_idle(void *handle)
    1337             : {
    1338           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1339             : 
    1340           0 :         return (RREG32_SOC15(VCN, 0, mmUVD_STATUS) == UVD_STATUS__IDLE);
    1341             : }
    1342             : 
    1343           0 : static int vcn_v1_0_wait_for_idle(void *handle)
    1344             : {
    1345           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1346             :         int ret;
    1347             : 
    1348           0 :         ret = SOC15_WAIT_ON_RREG(VCN, 0, mmUVD_STATUS, UVD_STATUS__IDLE,
    1349             :                 UVD_STATUS__IDLE);
    1350             : 
    1351           0 :         return ret;
    1352             : }
    1353             : 
    1354           0 : static int vcn_v1_0_set_clockgating_state(void *handle,
    1355             :                                           enum amd_clockgating_state state)
    1356             : {
    1357           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1358           0 :         bool enable = (state == AMD_CG_STATE_GATE);
    1359             : 
    1360           0 :         if (enable) {
    1361             :                 /* wait for STATUS to clear */
    1362           0 :                 if (!vcn_v1_0_is_idle(handle))
    1363             :                         return -EBUSY;
    1364           0 :                 vcn_v1_0_enable_clock_gating(adev);
    1365             :         } else {
    1366             :                 /* disable HW gating and enable Sw gating */
    1367           0 :                 vcn_v1_0_disable_clock_gating(adev);
    1368             :         }
    1369             :         return 0;
    1370             : }
    1371             : 
    1372             : /**
    1373             :  * vcn_v1_0_dec_ring_get_rptr - get read pointer
    1374             :  *
    1375             :  * @ring: amdgpu_ring pointer
    1376             :  *
    1377             :  * Returns the current hardware read pointer
    1378             :  */
    1379           0 : static uint64_t vcn_v1_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
    1380             : {
    1381           0 :         struct amdgpu_device *adev = ring->adev;
    1382             : 
    1383           0 :         return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_RPTR);
    1384             : }
    1385             : 
    1386             : /**
    1387             :  * vcn_v1_0_dec_ring_get_wptr - get write pointer
    1388             :  *
    1389             :  * @ring: amdgpu_ring pointer
    1390             :  *
    1391             :  * Returns the current hardware write pointer
    1392             :  */
    1393           0 : static uint64_t vcn_v1_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
    1394             : {
    1395           0 :         struct amdgpu_device *adev = ring->adev;
    1396             : 
    1397           0 :         return RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR);
    1398             : }
    1399             : 
    1400             : /**
    1401             :  * vcn_v1_0_dec_ring_set_wptr - set write pointer
    1402             :  *
    1403             :  * @ring: amdgpu_ring pointer
    1404             :  *
    1405             :  * Commits the write pointer to the hardware
    1406             :  */
    1407           0 : static void vcn_v1_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
    1408             : {
    1409           0 :         struct amdgpu_device *adev = ring->adev;
    1410             : 
    1411           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
    1412           0 :                 WREG32_SOC15(UVD, 0, mmUVD_SCRATCH2,
    1413             :                         lower_32_bits(ring->wptr) | 0x80000000);
    1414             : 
    1415           0 :         WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
    1416           0 : }
    1417             : 
    1418             : /**
    1419             :  * vcn_v1_0_dec_ring_insert_start - insert a start command
    1420             :  *
    1421             :  * @ring: amdgpu_ring pointer
    1422             :  *
    1423             :  * Write a start command to the ring.
    1424             :  */
    1425           0 : static void vcn_v1_0_dec_ring_insert_start(struct amdgpu_ring *ring)
    1426             : {
    1427           0 :         struct amdgpu_device *adev = ring->adev;
    1428             : 
    1429           0 :         amdgpu_ring_write(ring,
    1430           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
    1431           0 :         amdgpu_ring_write(ring, 0);
    1432           0 :         amdgpu_ring_write(ring,
    1433           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1434           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_START << 1);
    1435           0 : }
    1436             : 
    1437             : /**
    1438             :  * vcn_v1_0_dec_ring_insert_end - insert a end command
    1439             :  *
    1440             :  * @ring: amdgpu_ring pointer
    1441             :  *
    1442             :  * Write a end command to the ring.
    1443             :  */
    1444           0 : static void vcn_v1_0_dec_ring_insert_end(struct amdgpu_ring *ring)
    1445             : {
    1446           0 :         struct amdgpu_device *adev = ring->adev;
    1447             : 
    1448           0 :         amdgpu_ring_write(ring,
    1449           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1450           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_PACKET_END << 1);
    1451           0 : }
    1452             : 
    1453             : /**
    1454             :  * vcn_v1_0_dec_ring_emit_fence - emit an fence & trap command
    1455             :  *
    1456             :  * @ring: amdgpu_ring pointer
    1457             :  * @addr: address
    1458             :  * @seq: sequence number
    1459             :  * @flags: fence related flags
    1460             :  *
    1461             :  * Write a fence and a trap command to the ring.
    1462             :  */
    1463           0 : static void vcn_v1_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
    1464             :                                      unsigned flags)
    1465             : {
    1466           0 :         struct amdgpu_device *adev = ring->adev;
    1467             : 
    1468           0 :         WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
    1469             : 
    1470           0 :         amdgpu_ring_write(ring,
    1471           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0));
    1472           0 :         amdgpu_ring_write(ring, seq);
    1473           0 :         amdgpu_ring_write(ring,
    1474           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
    1475           0 :         amdgpu_ring_write(ring, addr & 0xffffffff);
    1476           0 :         amdgpu_ring_write(ring,
    1477           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
    1478           0 :         amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
    1479           0 :         amdgpu_ring_write(ring,
    1480           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1481           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_FENCE << 1);
    1482             : 
    1483           0 :         amdgpu_ring_write(ring,
    1484           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
    1485           0 :         amdgpu_ring_write(ring, 0);
    1486           0 :         amdgpu_ring_write(ring,
    1487           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
    1488           0 :         amdgpu_ring_write(ring, 0);
    1489           0 :         amdgpu_ring_write(ring,
    1490           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1491           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_TRAP << 1);
    1492           0 : }
    1493             : 
    1494             : /**
    1495             :  * vcn_v1_0_dec_ring_emit_ib - execute indirect buffer
    1496             :  *
    1497             :  * @ring: amdgpu_ring pointer
    1498             :  * @job: job to retrieve vmid from
    1499             :  * @ib: indirect buffer to execute
    1500             :  * @flags: unused
    1501             :  *
    1502             :  * Write ring commands to execute the indirect buffer
    1503             :  */
    1504           0 : static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
    1505             :                                         struct amdgpu_job *job,
    1506             :                                         struct amdgpu_ib *ib,
    1507             :                                         uint32_t flags)
    1508             : {
    1509           0 :         struct amdgpu_device *adev = ring->adev;
    1510           0 :         unsigned vmid = AMDGPU_JOB_GET_VMID(job);
    1511             : 
    1512           0 :         amdgpu_ring_write(ring,
    1513           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0));
    1514           0 :         amdgpu_ring_write(ring, vmid);
    1515             : 
    1516           0 :         amdgpu_ring_write(ring,
    1517           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
    1518           0 :         amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
    1519           0 :         amdgpu_ring_write(ring,
    1520           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH), 0));
    1521           0 :         amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
    1522           0 :         amdgpu_ring_write(ring,
    1523           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_IB_SIZE), 0));
    1524           0 :         amdgpu_ring_write(ring, ib->length_dw);
    1525           0 : }
    1526             : 
    1527           0 : static void vcn_v1_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring,
    1528             :                                             uint32_t reg, uint32_t val,
    1529             :                                             uint32_t mask)
    1530             : {
    1531           0 :         struct amdgpu_device *adev = ring->adev;
    1532             : 
    1533           0 :         amdgpu_ring_write(ring,
    1534           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
    1535           0 :         amdgpu_ring_write(ring, reg << 2);
    1536           0 :         amdgpu_ring_write(ring,
    1537           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
    1538           0 :         amdgpu_ring_write(ring, val);
    1539           0 :         amdgpu_ring_write(ring,
    1540           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GP_SCRATCH8), 0));
    1541           0 :         amdgpu_ring_write(ring, mask);
    1542           0 :         amdgpu_ring_write(ring,
    1543           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1544           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_REG_READ_COND_WAIT << 1);
    1545           0 : }
    1546             : 
    1547           0 : static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
    1548             :                                             unsigned vmid, uint64_t pd_addr)
    1549             : {
    1550           0 :         struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
    1551             :         uint32_t data0, data1, mask;
    1552             : 
    1553           0 :         pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
    1554             : 
    1555             :         /* wait for register write */
    1556           0 :         data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;
    1557           0 :         data1 = lower_32_bits(pd_addr);
    1558           0 :         mask = 0xffffffff;
    1559           0 :         vcn_v1_0_dec_ring_emit_reg_wait(ring, data0, data1, mask);
    1560           0 : }
    1561             : 
    1562           0 : static void vcn_v1_0_dec_ring_emit_wreg(struct amdgpu_ring *ring,
    1563             :                                         uint32_t reg, uint32_t val)
    1564             : {
    1565           0 :         struct amdgpu_device *adev = ring->adev;
    1566             : 
    1567           0 :         amdgpu_ring_write(ring,
    1568           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA0), 0));
    1569           0 :         amdgpu_ring_write(ring, reg << 2);
    1570           0 :         amdgpu_ring_write(ring,
    1571           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_DATA1), 0));
    1572           0 :         amdgpu_ring_write(ring, val);
    1573           0 :         amdgpu_ring_write(ring,
    1574           0 :                 PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_GPCOM_VCPU_CMD), 0));
    1575           0 :         amdgpu_ring_write(ring, VCN_DEC_CMD_WRITE_REG << 1);
    1576           0 : }
    1577             : 
    1578             : /**
    1579             :  * vcn_v1_0_enc_ring_get_rptr - get enc read pointer
    1580             :  *
    1581             :  * @ring: amdgpu_ring pointer
    1582             :  *
    1583             :  * Returns the current hardware enc read pointer
    1584             :  */
    1585           0 : static uint64_t vcn_v1_0_enc_ring_get_rptr(struct amdgpu_ring *ring)
    1586             : {
    1587           0 :         struct amdgpu_device *adev = ring->adev;
    1588             : 
    1589           0 :         if (ring == &adev->vcn.inst->ring_enc[0])
    1590           0 :                 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR);
    1591             :         else
    1592           0 :                 return RREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2);
    1593             : }
    1594             : 
    1595             :  /**
    1596             :  * vcn_v1_0_enc_ring_get_wptr - get enc write pointer
    1597             :  *
    1598             :  * @ring: amdgpu_ring pointer
    1599             :  *
    1600             :  * Returns the current hardware enc write pointer
    1601             :  */
    1602           0 : static uint64_t vcn_v1_0_enc_ring_get_wptr(struct amdgpu_ring *ring)
    1603             : {
    1604           0 :         struct amdgpu_device *adev = ring->adev;
    1605             : 
    1606           0 :         if (ring == &adev->vcn.inst->ring_enc[0])
    1607           0 :                 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);
    1608             :         else
    1609           0 :                 return RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);
    1610             : }
    1611             : 
    1612             :  /**
    1613             :  * vcn_v1_0_enc_ring_set_wptr - set enc write pointer
    1614             :  *
    1615             :  * @ring: amdgpu_ring pointer
    1616             :  *
    1617             :  * Commits the enc write pointer to the hardware
    1618             :  */
    1619           0 : static void vcn_v1_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
    1620             : {
    1621           0 :         struct amdgpu_device *adev = ring->adev;
    1622             : 
    1623           0 :         if (ring == &adev->vcn.inst->ring_enc[0])
    1624           0 :                 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR,
    1625             :                         lower_32_bits(ring->wptr));
    1626             :         else
    1627           0 :                 WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2,
    1628             :                         lower_32_bits(ring->wptr));
    1629           0 : }
    1630             : 
    1631             : /**
    1632             :  * vcn_v1_0_enc_ring_emit_fence - emit an enc fence & trap command
    1633             :  *
    1634             :  * @ring: amdgpu_ring pointer
    1635             :  * @addr: address
    1636             :  * @seq: sequence number
    1637             :  * @flags: fence related flags
    1638             :  *
    1639             :  * Write enc a fence and a trap command to the ring.
    1640             :  */
    1641           0 : static void vcn_v1_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
    1642             :                         u64 seq, unsigned flags)
    1643             : {
    1644           0 :         WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
    1645             : 
    1646           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_FENCE);
    1647           0 :         amdgpu_ring_write(ring, addr);
    1648           0 :         amdgpu_ring_write(ring, upper_32_bits(addr));
    1649           0 :         amdgpu_ring_write(ring, seq);
    1650           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_TRAP);
    1651           0 : }
    1652             : 
    1653           0 : static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring)
    1654             : {
    1655           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_END);
    1656           0 : }
    1657             : 
    1658             : /**
    1659             :  * vcn_v1_0_enc_ring_emit_ib - enc execute indirect buffer
    1660             :  *
    1661             :  * @ring: amdgpu_ring pointer
    1662             :  * @job: job to retrive vmid from
    1663             :  * @ib: indirect buffer to execute
    1664             :  * @flags: unused
    1665             :  *
    1666             :  * Write enc ring commands to execute the indirect buffer
    1667             :  */
    1668           0 : static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
    1669             :                                         struct amdgpu_job *job,
    1670             :                                         struct amdgpu_ib *ib,
    1671             :                                         uint32_t flags)
    1672             : {
    1673           0 :         unsigned vmid = AMDGPU_JOB_GET_VMID(job);
    1674             : 
    1675           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_IB);
    1676           0 :         amdgpu_ring_write(ring, vmid);
    1677           0 :         amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
    1678           0 :         amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
    1679           0 :         amdgpu_ring_write(ring, ib->length_dw);
    1680           0 : }
    1681             : 
    1682           0 : static void vcn_v1_0_enc_ring_emit_reg_wait(struct amdgpu_ring *ring,
    1683             :                                             uint32_t reg, uint32_t val,
    1684             :                                             uint32_t mask)
    1685             : {
    1686           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT);
    1687           0 :         amdgpu_ring_write(ring, reg << 2);
    1688           0 :         amdgpu_ring_write(ring, mask);
    1689           0 :         amdgpu_ring_write(ring, val);
    1690           0 : }
    1691             : 
    1692           0 : static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
    1693             :                                             unsigned int vmid, uint64_t pd_addr)
    1694             : {
    1695           0 :         struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
    1696             : 
    1697           0 :         pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
    1698             : 
    1699             :         /* wait for reg writes */
    1700           0 :         vcn_v1_0_enc_ring_emit_reg_wait(ring, hub->ctx0_ptb_addr_lo32 +
    1701           0 :                                         vmid * hub->ctx_addr_distance,
    1702             :                                         lower_32_bits(pd_addr), 0xffffffff);
    1703           0 : }
    1704             : 
    1705           0 : static void vcn_v1_0_enc_ring_emit_wreg(struct amdgpu_ring *ring,
    1706             :                                         uint32_t reg, uint32_t val)
    1707             : {
    1708           0 :         amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE);
    1709           0 :         amdgpu_ring_write(ring, reg << 2);
    1710           0 :         amdgpu_ring_write(ring, val);
    1711           0 : }
    1712             : 
    1713           0 : static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,
    1714             :                                         struct amdgpu_irq_src *source,
    1715             :                                         unsigned type,
    1716             :                                         enum amdgpu_interrupt_state state)
    1717             : {
    1718           0 :         return 0;
    1719             : }
    1720             : 
    1721           0 : static int vcn_v1_0_process_interrupt(struct amdgpu_device *adev,
    1722             :                                       struct amdgpu_irq_src *source,
    1723             :                                       struct amdgpu_iv_entry *entry)
    1724             : {
    1725           0 :         DRM_DEBUG("IH: VCN TRAP\n");
    1726             : 
    1727           0 :         switch (entry->src_id) {
    1728             :         case 124:
    1729           0 :                 amdgpu_fence_process(&adev->vcn.inst->ring_dec);
    1730           0 :                 break;
    1731             :         case 119:
    1732           0 :                 amdgpu_fence_process(&adev->vcn.inst->ring_enc[0]);
    1733           0 :                 break;
    1734             :         case 120:
    1735           0 :                 amdgpu_fence_process(&adev->vcn.inst->ring_enc[1]);
    1736           0 :                 break;
    1737             :         default:
    1738           0 :                 DRM_ERROR("Unhandled interrupt: %d %d\n",
    1739             :                           entry->src_id, entry->src_data[0]);
    1740           0 :                 break;
    1741             :         }
    1742             : 
    1743           0 :         return 0;
    1744             : }
    1745             : 
    1746           0 : static void vcn_v1_0_dec_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
    1747             : {
    1748           0 :         struct amdgpu_device *adev = ring->adev;
    1749             :         int i;
    1750             : 
    1751           0 :         WARN_ON(ring->wptr % 2 || count % 2);
    1752             : 
    1753           0 :         for (i = 0; i < count / 2; i++) {
    1754           0 :                 amdgpu_ring_write(ring, PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_NO_OP), 0));
    1755           0 :                 amdgpu_ring_write(ring, 0);
    1756             :         }
    1757           0 : }
    1758             : 
    1759           0 : static int vcn_v1_0_set_powergating_state(void *handle,
    1760             :                                           enum amd_powergating_state state)
    1761             : {
    1762             :         /* This doesn't actually powergate the VCN block.
    1763             :          * That's done in the dpm code via the SMC.  This
    1764             :          * just re-inits the block as necessary.  The actual
    1765             :          * gating still happens in the dpm code.  We should
    1766             :          * revisit this when there is a cleaner line between
    1767             :          * the smc and the hw blocks
    1768             :          */
    1769             :         int ret;
    1770           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
    1771             : 
    1772           0 :         if(state == adev->vcn.cur_state)
    1773             :                 return 0;
    1774             : 
    1775           0 :         if (state == AMD_PG_STATE_GATE)
    1776           0 :                 ret = vcn_v1_0_stop(adev);
    1777             :         else
    1778           0 :                 ret = vcn_v1_0_start(adev);
    1779             : 
    1780           0 :         if(!ret)
    1781           0 :                 adev->vcn.cur_state = state;
    1782             :         return ret;
    1783             : }
    1784             : 
    1785           0 : static void vcn_v1_0_idle_work_handler(struct work_struct *work)
    1786             : {
    1787           0 :         struct amdgpu_device *adev =
    1788           0 :                 container_of(work, struct amdgpu_device, vcn.idle_work.work);
    1789           0 :         unsigned int fences = 0, i;
    1790             : 
    1791           0 :         for (i = 0; i < adev->vcn.num_enc_rings; ++i)
    1792           0 :                 fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_enc[i]);
    1793             : 
    1794           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
    1795             :                 struct dpg_pause_state new_state;
    1796             : 
    1797           0 :                 if (fences)
    1798           0 :                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
    1799             :                 else
    1800           0 :                         new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
    1801             : 
    1802           0 :                 if (amdgpu_fence_count_emitted(&adev->jpeg.inst->ring_dec))
    1803           0 :                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
    1804             :                 else
    1805           0 :                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
    1806             : 
    1807           0 :                 adev->vcn.pause_dpg_mode(adev, 0, &new_state);
    1808             :         }
    1809             : 
    1810           0 :         fences += amdgpu_fence_count_emitted(&adev->jpeg.inst->ring_dec);
    1811           0 :         fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_dec);
    1812             : 
    1813           0 :         if (fences == 0) {
    1814           0 :                 amdgpu_gfx_off_ctrl(adev, true);
    1815           0 :                 if (adev->pm.dpm_enabled)
    1816           0 :                         amdgpu_dpm_enable_uvd(adev, false);
    1817             :                 else
    1818           0 :                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
    1819             :                                AMD_PG_STATE_GATE);
    1820             :         } else {
    1821           0 :                 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
    1822             :         }
    1823           0 : }
    1824             : 
    1825           0 : static void vcn_v1_0_ring_begin_use(struct amdgpu_ring *ring)
    1826             : {
    1827           0 :         struct  amdgpu_device *adev = ring->adev;
    1828           0 :         bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
    1829             : 
    1830           0 :         mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
    1831             : 
    1832           0 :         if (amdgpu_fence_wait_empty(&ring->adev->jpeg.inst->ring_dec))
    1833           0 :                 DRM_ERROR("VCN dec: jpeg dec ring may not be empty\n");
    1834             : 
    1835           0 :         vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
    1836             : 
    1837           0 : }
    1838             : 
    1839           0 : void vcn_v1_0_set_pg_for_begin_use(struct amdgpu_ring *ring, bool set_clocks)
    1840             : {
    1841           0 :         struct amdgpu_device *adev = ring->adev;
    1842             : 
    1843           0 :         if (set_clocks) {
    1844           0 :                 amdgpu_gfx_off_ctrl(adev, false);
    1845           0 :                 if (adev->pm.dpm_enabled)
    1846           0 :                         amdgpu_dpm_enable_uvd(adev, true);
    1847             :                 else
    1848           0 :                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
    1849             :                                AMD_PG_STATE_UNGATE);
    1850             :         }
    1851             : 
    1852           0 :         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
    1853             :                 struct dpg_pause_state new_state;
    1854             :                 unsigned int fences = 0, i;
    1855             : 
    1856           0 :                 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
    1857           0 :                         fences += amdgpu_fence_count_emitted(&adev->vcn.inst->ring_enc[i]);
    1858             : 
    1859           0 :                 if (fences)
    1860           0 :                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
    1861             :                 else
    1862           0 :                         new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
    1863             : 
    1864           0 :                 if (amdgpu_fence_count_emitted(&adev->jpeg.inst->ring_dec))
    1865           0 :                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
    1866             :                 else
    1867           0 :                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
    1868             : 
    1869           0 :                 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
    1870           0 :                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
    1871           0 :                 else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
    1872           0 :                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
    1873             : 
    1874           0 :                 adev->vcn.pause_dpg_mode(adev, 0, &new_state);
    1875             :         }
    1876           0 : }
    1877             : 
    1878           0 : void vcn_v1_0_ring_end_use(struct amdgpu_ring *ring)
    1879             : {
    1880           0 :         schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
    1881           0 :         mutex_unlock(&ring->adev->vcn.vcn1_jpeg1_workaround);
    1882           0 : }
    1883             : 
    1884             : static const struct amd_ip_funcs vcn_v1_0_ip_funcs = {
    1885             :         .name = "vcn_v1_0",
    1886             :         .early_init = vcn_v1_0_early_init,
    1887             :         .late_init = NULL,
    1888             :         .sw_init = vcn_v1_0_sw_init,
    1889             :         .sw_fini = vcn_v1_0_sw_fini,
    1890             :         .hw_init = vcn_v1_0_hw_init,
    1891             :         .hw_fini = vcn_v1_0_hw_fini,
    1892             :         .suspend = vcn_v1_0_suspend,
    1893             :         .resume = vcn_v1_0_resume,
    1894             :         .is_idle = vcn_v1_0_is_idle,
    1895             :         .wait_for_idle = vcn_v1_0_wait_for_idle,
    1896             :         .check_soft_reset = NULL /* vcn_v1_0_check_soft_reset */,
    1897             :         .pre_soft_reset = NULL /* vcn_v1_0_pre_soft_reset */,
    1898             :         .soft_reset = NULL /* vcn_v1_0_soft_reset */,
    1899             :         .post_soft_reset = NULL /* vcn_v1_0_post_soft_reset */,
    1900             :         .set_clockgating_state = vcn_v1_0_set_clockgating_state,
    1901             :         .set_powergating_state = vcn_v1_0_set_powergating_state,
    1902             : };
    1903             : 
    1904             : /*
    1905             :  * It is a hardware issue that VCN can't handle a GTT TMZ buffer on
    1906             :  * CHIP_RAVEN series ASIC. Move such a GTT TMZ buffer to VRAM domain
    1907             :  * before command submission as a workaround.
    1908             :  */
    1909           0 : static int vcn_v1_0_validate_bo(struct amdgpu_cs_parser *parser,
    1910             :                                 struct amdgpu_job *job,
    1911             :                                 uint64_t addr)
    1912             : {
    1913           0 :         struct ttm_operation_ctx ctx = { false, false };
    1914           0 :         struct amdgpu_fpriv *fpriv = parser->filp->driver_priv;
    1915           0 :         struct amdgpu_vm *vm = &fpriv->vm;
    1916             :         struct amdgpu_bo_va_mapping *mapping;
    1917             :         struct amdgpu_bo *bo;
    1918             :         int r;
    1919             : 
    1920           0 :         addr &= AMDGPU_GMC_HOLE_MASK;
    1921           0 :         if (addr & 0x7) {
    1922           0 :                 DRM_ERROR("VCN messages must be 8 byte aligned!\n");
    1923             :                 return -EINVAL;
    1924             :         }
    1925             : 
    1926           0 :         mapping = amdgpu_vm_bo_lookup_mapping(vm, addr/AMDGPU_GPU_PAGE_SIZE);
    1927           0 :         if (!mapping || !mapping->bo_va || !mapping->bo_va->base.bo)
    1928             :                 return -EINVAL;
    1929             : 
    1930           0 :         bo = mapping->bo_va->base.bo;
    1931           0 :         if (!(bo->flags & AMDGPU_GEM_CREATE_ENCRYPTED))
    1932             :                 return 0;
    1933             : 
    1934           0 :         amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_VRAM);
    1935           0 :         r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
    1936           0 :         if (r) {
    1937           0 :                 DRM_ERROR("Failed to validate the VCN message BO (%d)!\n", r);
    1938             :                 return r;
    1939             :         }
    1940             : 
    1941             :         return r;
    1942             : }
    1943             : 
    1944           0 : static int vcn_v1_0_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
    1945             :                                            struct amdgpu_job *job,
    1946             :                                            struct amdgpu_ib *ib)
    1947             : {
    1948           0 :         uint32_t msg_lo = 0, msg_hi = 0;
    1949             :         int i, r;
    1950             : 
    1951           0 :         if (!(ib->flags & AMDGPU_IB_FLAGS_SECURE))
    1952             :                 return 0;
    1953             : 
    1954           0 :         for (i = 0; i < ib->length_dw; i += 2) {
    1955           0 :                 uint32_t reg = amdgpu_ib_get_value(ib, i);
    1956           0 :                 uint32_t val = amdgpu_ib_get_value(ib, i + 1);
    1957             : 
    1958           0 :                 if (reg == PACKET0(p->adev->vcn.internal.data0, 0)) {
    1959             :                         msg_lo = val;
    1960           0 :                 } else if (reg == PACKET0(p->adev->vcn.internal.data1, 0)) {
    1961             :                         msg_hi = val;
    1962           0 :                 } else if (reg == PACKET0(p->adev->vcn.internal.cmd, 0)) {
    1963           0 :                         r = vcn_v1_0_validate_bo(p, job,
    1964           0 :                                                  ((u64)msg_hi) << 32 | msg_lo);
    1965           0 :                         if (r)
    1966             :                                 return r;
    1967             :                 }
    1968             :         }
    1969             : 
    1970             :         return 0;
    1971             : }
    1972             : 
    1973             : static const struct amdgpu_ring_funcs vcn_v1_0_dec_ring_vm_funcs = {
    1974             :         .type = AMDGPU_RING_TYPE_VCN_DEC,
    1975             :         .align_mask = 0xf,
    1976             :         .support_64bit_ptrs = false,
    1977             :         .no_user_fence = true,
    1978             :         .secure_submission_supported = true,
    1979             :         .vmhub = AMDGPU_MMHUB_0,
    1980             :         .get_rptr = vcn_v1_0_dec_ring_get_rptr,
    1981             :         .get_wptr = vcn_v1_0_dec_ring_get_wptr,
    1982             :         .set_wptr = vcn_v1_0_dec_ring_set_wptr,
    1983             :         .patch_cs_in_place = vcn_v1_0_ring_patch_cs_in_place,
    1984             :         .emit_frame_size =
    1985             :                 6 + 6 + /* hdp invalidate / flush */
    1986             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
    1987             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
    1988             :                 8 + /* vcn_v1_0_dec_ring_emit_vm_flush */
    1989             :                 14 + 14 + /* vcn_v1_0_dec_ring_emit_fence x2 vm fence */
    1990             :                 6,
    1991             :         .emit_ib_size = 8, /* vcn_v1_0_dec_ring_emit_ib */
    1992             :         .emit_ib = vcn_v1_0_dec_ring_emit_ib,
    1993             :         .emit_fence = vcn_v1_0_dec_ring_emit_fence,
    1994             :         .emit_vm_flush = vcn_v1_0_dec_ring_emit_vm_flush,
    1995             :         .test_ring = amdgpu_vcn_dec_ring_test_ring,
    1996             :         .test_ib = amdgpu_vcn_dec_ring_test_ib,
    1997             :         .insert_nop = vcn_v1_0_dec_ring_insert_nop,
    1998             :         .insert_start = vcn_v1_0_dec_ring_insert_start,
    1999             :         .insert_end = vcn_v1_0_dec_ring_insert_end,
    2000             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    2001             :         .begin_use = vcn_v1_0_ring_begin_use,
    2002             :         .end_use = vcn_v1_0_ring_end_use,
    2003             :         .emit_wreg = vcn_v1_0_dec_ring_emit_wreg,
    2004             :         .emit_reg_wait = vcn_v1_0_dec_ring_emit_reg_wait,
    2005             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    2006             : };
    2007             : 
    2008             : static const struct amdgpu_ring_funcs vcn_v1_0_enc_ring_vm_funcs = {
    2009             :         .type = AMDGPU_RING_TYPE_VCN_ENC,
    2010             :         .align_mask = 0x3f,
    2011             :         .nop = VCN_ENC_CMD_NO_OP,
    2012             :         .support_64bit_ptrs = false,
    2013             :         .no_user_fence = true,
    2014             :         .vmhub = AMDGPU_MMHUB_0,
    2015             :         .get_rptr = vcn_v1_0_enc_ring_get_rptr,
    2016             :         .get_wptr = vcn_v1_0_enc_ring_get_wptr,
    2017             :         .set_wptr = vcn_v1_0_enc_ring_set_wptr,
    2018             :         .emit_frame_size =
    2019             :                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
    2020             :                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
    2021             :                 4 + /* vcn_v1_0_enc_ring_emit_vm_flush */
    2022             :                 5 + 5 + /* vcn_v1_0_enc_ring_emit_fence x2 vm fence */
    2023             :                 1, /* vcn_v1_0_enc_ring_insert_end */
    2024             :         .emit_ib_size = 5, /* vcn_v1_0_enc_ring_emit_ib */
    2025             :         .emit_ib = vcn_v1_0_enc_ring_emit_ib,
    2026             :         .emit_fence = vcn_v1_0_enc_ring_emit_fence,
    2027             :         .emit_vm_flush = vcn_v1_0_enc_ring_emit_vm_flush,
    2028             :         .test_ring = amdgpu_vcn_enc_ring_test_ring,
    2029             :         .test_ib = amdgpu_vcn_enc_ring_test_ib,
    2030             :         .insert_nop = amdgpu_ring_insert_nop,
    2031             :         .insert_end = vcn_v1_0_enc_ring_insert_end,
    2032             :         .pad_ib = amdgpu_ring_generic_pad_ib,
    2033             :         .begin_use = vcn_v1_0_ring_begin_use,
    2034             :         .end_use = vcn_v1_0_ring_end_use,
    2035             :         .emit_wreg = vcn_v1_0_enc_ring_emit_wreg,
    2036             :         .emit_reg_wait = vcn_v1_0_enc_ring_emit_reg_wait,
    2037             :         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
    2038             : };
    2039             : 
    2040             : static void vcn_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
    2041             : {
    2042           0 :         adev->vcn.inst->ring_dec.funcs = &vcn_v1_0_dec_ring_vm_funcs;
    2043           0 :         DRM_INFO("VCN decode is enabled in VM mode\n");
    2044             : }
    2045             : 
    2046             : static void vcn_v1_0_set_enc_ring_funcs(struct amdgpu_device *adev)
    2047             : {
    2048             :         int i;
    2049             : 
    2050           0 :         for (i = 0; i < adev->vcn.num_enc_rings; ++i)
    2051           0 :                 adev->vcn.inst->ring_enc[i].funcs = &vcn_v1_0_enc_ring_vm_funcs;
    2052             : 
    2053           0 :         DRM_INFO("VCN encode is enabled in VM mode\n");
    2054             : }
    2055             : 
    2056             : static const struct amdgpu_irq_src_funcs vcn_v1_0_irq_funcs = {
    2057             :         .set = vcn_v1_0_set_interrupt_state,
    2058             :         .process = vcn_v1_0_process_interrupt,
    2059             : };
    2060             : 
    2061             : static void vcn_v1_0_set_irq_funcs(struct amdgpu_device *adev)
    2062             : {
    2063           0 :         adev->vcn.inst->irq.num_types = adev->vcn.num_enc_rings + 2;
    2064           0 :         adev->vcn.inst->irq.funcs = &vcn_v1_0_irq_funcs;
    2065             : }
    2066             : 
    2067             : const struct amdgpu_ip_block_version vcn_v1_0_ip_block =
    2068             : {
    2069             :                 .type = AMD_IP_BLOCK_TYPE_VCN,
    2070             :                 .major = 1,
    2071             :                 .minor = 0,
    2072             :                 .rev = 0,
    2073             :                 .funcs = &vcn_v1_0_ip_funcs,
    2074             : };

Generated by: LCOV version 1.14