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

          Line data    Source code
       1             : /*
       2             :  * Copyright 2014 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             :  * Authors: Christian König <christian.koenig@amd.com>
      23             :  */
      24             : 
      25             : #include <linux/delay.h>
      26             : #include <linux/firmware.h>
      27             : 
      28             : #include "amdgpu.h"
      29             : #include "amdgpu_uvd.h"
      30             : #include "vid.h"
      31             : #include "uvd/uvd_5_0_d.h"
      32             : #include "uvd/uvd_5_0_sh_mask.h"
      33             : #include "oss/oss_2_0_d.h"
      34             : #include "oss/oss_2_0_sh_mask.h"
      35             : #include "bif/bif_5_0_d.h"
      36             : #include "vi.h"
      37             : #include "smu/smu_7_1_2_d.h"
      38             : #include "smu/smu_7_1_2_sh_mask.h"
      39             : #include "ivsrcid/ivsrcid_vislands30.h"
      40             : 
      41             : static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev);
      42             : static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev);
      43             : static int uvd_v5_0_start(struct amdgpu_device *adev);
      44             : static void uvd_v5_0_stop(struct amdgpu_device *adev);
      45             : static int uvd_v5_0_set_clockgating_state(void *handle,
      46             :                                           enum amd_clockgating_state state);
      47             : static void uvd_v5_0_enable_mgcg(struct amdgpu_device *adev,
      48             :                                  bool enable);
      49             : /**
      50             :  * uvd_v5_0_ring_get_rptr - get read pointer
      51             :  *
      52             :  * @ring: amdgpu_ring pointer
      53             :  *
      54             :  * Returns the current hardware read pointer
      55             :  */
      56           0 : static uint64_t uvd_v5_0_ring_get_rptr(struct amdgpu_ring *ring)
      57             : {
      58           0 :         struct amdgpu_device *adev = ring->adev;
      59             : 
      60           0 :         return RREG32(mmUVD_RBC_RB_RPTR);
      61             : }
      62             : 
      63             : /**
      64             :  * uvd_v5_0_ring_get_wptr - get write pointer
      65             :  *
      66             :  * @ring: amdgpu_ring pointer
      67             :  *
      68             :  * Returns the current hardware write pointer
      69             :  */
      70           0 : static uint64_t uvd_v5_0_ring_get_wptr(struct amdgpu_ring *ring)
      71             : {
      72           0 :         struct amdgpu_device *adev = ring->adev;
      73             : 
      74           0 :         return RREG32(mmUVD_RBC_RB_WPTR);
      75             : }
      76             : 
      77             : /**
      78             :  * uvd_v5_0_ring_set_wptr - set write pointer
      79             :  *
      80             :  * @ring: amdgpu_ring pointer
      81             :  *
      82             :  * Commits the write pointer to the hardware
      83             :  */
      84           0 : static void uvd_v5_0_ring_set_wptr(struct amdgpu_ring *ring)
      85             : {
      86           0 :         struct amdgpu_device *adev = ring->adev;
      87             : 
      88           0 :         WREG32(mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
      89           0 : }
      90             : 
      91           0 : static int uvd_v5_0_early_init(void *handle)
      92             : {
      93           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
      94           0 :         adev->uvd.num_uvd_inst = 1;
      95             : 
      96           0 :         uvd_v5_0_set_ring_funcs(adev);
      97           0 :         uvd_v5_0_set_irq_funcs(adev);
      98             : 
      99           0 :         return 0;
     100             : }
     101             : 
     102           0 : static int uvd_v5_0_sw_init(void *handle)
     103             : {
     104             :         struct amdgpu_ring *ring;
     105           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     106             :         int r;
     107             : 
     108             :         /* UVD TRAP */
     109           0 :         r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, VISLANDS30_IV_SRCID_UVD_SYSTEM_MESSAGE, &adev->uvd.inst->irq);
     110           0 :         if (r)
     111             :                 return r;
     112             : 
     113           0 :         r = amdgpu_uvd_sw_init(adev);
     114           0 :         if (r)
     115             :                 return r;
     116             : 
     117           0 :         ring = &adev->uvd.inst->ring;
     118           0 :         sprintf(ring->name, "uvd");
     119           0 :         r = amdgpu_ring_init(adev, ring, 512, &adev->uvd.inst->irq, 0,
     120             :                              AMDGPU_RING_PRIO_DEFAULT, NULL);
     121           0 :         if (r)
     122             :                 return r;
     123             : 
     124           0 :         r = amdgpu_uvd_resume(adev);
     125           0 :         if (r)
     126             :                 return r;
     127             : 
     128           0 :         r = amdgpu_uvd_entity_init(adev);
     129             : 
     130           0 :         return r;
     131             : }
     132             : 
     133           0 : static int uvd_v5_0_sw_fini(void *handle)
     134             : {
     135             :         int r;
     136           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     137             : 
     138           0 :         r = amdgpu_uvd_suspend(adev);
     139           0 :         if (r)
     140             :                 return r;
     141             : 
     142           0 :         return amdgpu_uvd_sw_fini(adev);
     143             : }
     144             : 
     145             : /**
     146             :  * uvd_v5_0_hw_init - start and test UVD block
     147             :  *
     148             :  * @handle: handle used to pass amdgpu_device pointer
     149             :  *
     150             :  * Initialize the hardware, boot up the VCPU and do some testing
     151             :  */
     152           0 : static int uvd_v5_0_hw_init(void *handle)
     153             : {
     154           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     155           0 :         struct amdgpu_ring *ring = &adev->uvd.inst->ring;
     156             :         uint32_t tmp;
     157             :         int r;
     158             : 
     159           0 :         amdgpu_asic_set_uvd_clocks(adev, 10000, 10000);
     160           0 :         uvd_v5_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE);
     161           0 :         uvd_v5_0_enable_mgcg(adev, true);
     162             : 
     163           0 :         r = amdgpu_ring_test_helper(ring);
     164           0 :         if (r)
     165             :                 goto done;
     166             : 
     167           0 :         r = amdgpu_ring_alloc(ring, 10);
     168           0 :         if (r) {
     169           0 :                 DRM_ERROR("amdgpu: ring failed to lock UVD ring (%d).\n", r);
     170           0 :                 goto done;
     171             :         }
     172             : 
     173           0 :         tmp = PACKET0(mmUVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
     174           0 :         amdgpu_ring_write(ring, tmp);
     175           0 :         amdgpu_ring_write(ring, 0xFFFFF);
     176             : 
     177           0 :         tmp = PACKET0(mmUVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
     178           0 :         amdgpu_ring_write(ring, tmp);
     179           0 :         amdgpu_ring_write(ring, 0xFFFFF);
     180             : 
     181           0 :         tmp = PACKET0(mmUVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
     182           0 :         amdgpu_ring_write(ring, tmp);
     183           0 :         amdgpu_ring_write(ring, 0xFFFFF);
     184             : 
     185             :         /* Clear timeout status bits */
     186           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_TIMEOUT_STATUS, 0));
     187           0 :         amdgpu_ring_write(ring, 0x8);
     188             : 
     189           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_SEMA_CNTL, 0));
     190           0 :         amdgpu_ring_write(ring, 3);
     191             : 
     192           0 :         amdgpu_ring_commit(ring);
     193             : 
     194             : done:
     195           0 :         if (!r)
     196           0 :                 DRM_INFO("UVD initialized successfully.\n");
     197             : 
     198           0 :         return r;
     199             : 
     200             : }
     201             : 
     202             : /**
     203             :  * uvd_v5_0_hw_fini - stop the hardware block
     204             :  *
     205             :  * @handle: handle used to pass amdgpu_device pointer
     206             :  *
     207             :  * Stop the UVD block, mark ring as not ready any more
     208             :  */
     209           0 : static int uvd_v5_0_hw_fini(void *handle)
     210             : {
     211           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     212             : 
     213           0 :         cancel_delayed_work_sync(&adev->uvd.idle_work);
     214             : 
     215           0 :         if (RREG32(mmUVD_STATUS) != 0)
     216           0 :                 uvd_v5_0_stop(adev);
     217             : 
     218           0 :         return 0;
     219             : }
     220             : 
     221           0 : static int uvd_v5_0_suspend(void *handle)
     222             : {
     223             :         int r;
     224           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     225             : 
     226             :         /*
     227             :          * Proper cleanups before halting the HW engine:
     228             :          *   - cancel the delayed idle work
     229             :          *   - enable powergating
     230             :          *   - enable clockgating
     231             :          *   - disable dpm
     232             :          *
     233             :          * TODO: to align with the VCN implementation, move the
     234             :          * jobs for clockgating/powergating/dpm setting to
     235             :          * ->set_powergating_state().
     236             :          */
     237           0 :         cancel_delayed_work_sync(&adev->uvd.idle_work);
     238             : 
     239           0 :         if (adev->pm.dpm_enabled) {
     240           0 :                 amdgpu_dpm_enable_uvd(adev, false);
     241             :         } else {
     242           0 :                 amdgpu_asic_set_uvd_clocks(adev, 0, 0);
     243             :                 /* shutdown the UVD block */
     244           0 :                 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
     245             :                                                        AMD_PG_STATE_GATE);
     246           0 :                 amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_UVD,
     247             :                                                        AMD_CG_STATE_GATE);
     248             :         }
     249             : 
     250           0 :         r = uvd_v5_0_hw_fini(adev);
     251           0 :         if (r)
     252             :                 return r;
     253             : 
     254           0 :         return amdgpu_uvd_suspend(adev);
     255             : }
     256             : 
     257           0 : static int uvd_v5_0_resume(void *handle)
     258             : {
     259             :         int r;
     260           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     261             : 
     262           0 :         r = amdgpu_uvd_resume(adev);
     263           0 :         if (r)
     264             :                 return r;
     265             : 
     266           0 :         return uvd_v5_0_hw_init(adev);
     267             : }
     268             : 
     269             : /**
     270             :  * uvd_v5_0_mc_resume - memory controller programming
     271             :  *
     272             :  * @adev: amdgpu_device pointer
     273             :  *
     274             :  * Let the UVD memory controller know it's offsets
     275             :  */
     276           0 : static void uvd_v5_0_mc_resume(struct amdgpu_device *adev)
     277             : {
     278             :         uint64_t offset;
     279             :         uint32_t size;
     280             : 
     281             :         /* program memory controller bits 0-27 */
     282           0 :         WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
     283             :                         lower_32_bits(adev->uvd.inst->gpu_addr));
     284           0 :         WREG32(mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
     285             :                         upper_32_bits(adev->uvd.inst->gpu_addr));
     286             : 
     287           0 :         offset = AMDGPU_UVD_FIRMWARE_OFFSET;
     288           0 :         size = AMDGPU_UVD_FIRMWARE_SIZE(adev);
     289           0 :         WREG32(mmUVD_VCPU_CACHE_OFFSET0, offset >> 3);
     290           0 :         WREG32(mmUVD_VCPU_CACHE_SIZE0, size);
     291             : 
     292           0 :         offset += size;
     293           0 :         size = AMDGPU_UVD_HEAP_SIZE;
     294           0 :         WREG32(mmUVD_VCPU_CACHE_OFFSET1, offset >> 3);
     295           0 :         WREG32(mmUVD_VCPU_CACHE_SIZE1, size);
     296             : 
     297           0 :         offset += size;
     298           0 :         size = AMDGPU_UVD_STACK_SIZE +
     299           0 :                (AMDGPU_UVD_SESSION_SIZE * adev->uvd.max_handles);
     300           0 :         WREG32(mmUVD_VCPU_CACHE_OFFSET2, offset >> 3);
     301           0 :         WREG32(mmUVD_VCPU_CACHE_SIZE2, size);
     302             : 
     303           0 :         WREG32(mmUVD_UDEC_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
     304           0 :         WREG32(mmUVD_UDEC_DB_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
     305           0 :         WREG32(mmUVD_UDEC_DBW_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
     306           0 : }
     307             : 
     308             : /**
     309             :  * uvd_v5_0_start - start UVD block
     310             :  *
     311             :  * @adev: amdgpu_device pointer
     312             :  *
     313             :  * Setup and start the UVD block
     314             :  */
     315           0 : static int uvd_v5_0_start(struct amdgpu_device *adev)
     316             : {
     317           0 :         struct amdgpu_ring *ring = &adev->uvd.inst->ring;
     318             :         uint32_t rb_bufsz, tmp;
     319             :         uint32_t lmi_swap_cntl;
     320             :         uint32_t mp_swap_cntl;
     321             :         int i, j, r;
     322             : 
     323             :         /*disable DPG */
     324           0 :         WREG32_P(mmUVD_POWER_STATUS, 0, ~(1 << 2));
     325             : 
     326             :         /* disable byte swapping */
     327           0 :         lmi_swap_cntl = 0;
     328           0 :         mp_swap_cntl = 0;
     329             : 
     330           0 :         uvd_v5_0_mc_resume(adev);
     331             : 
     332             :         /* disable interupt */
     333           0 :         WREG32_P(mmUVD_MASTINT_EN, 0, ~(1 << 1));
     334             : 
     335             :         /* stall UMC and register bus before resetting VCPU */
     336           0 :         WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
     337           0 :         mdelay(1);
     338             : 
     339             :         /* put LMI, VCPU, RBC etc... into reset */
     340           0 :         WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__LMI_SOFT_RESET_MASK |
     341             :                 UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK | UVD_SOFT_RESET__LBSI_SOFT_RESET_MASK |
     342             :                 UVD_SOFT_RESET__RBC_SOFT_RESET_MASK | UVD_SOFT_RESET__CSM_SOFT_RESET_MASK |
     343             :                 UVD_SOFT_RESET__CXW_SOFT_RESET_MASK | UVD_SOFT_RESET__TAP_SOFT_RESET_MASK |
     344             :                 UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK);
     345           0 :         mdelay(5);
     346             : 
     347             :         /* take UVD block out of reset */
     348           0 :         WREG32_P(mmSRBM_SOFT_RESET, 0, ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
     349           0 :         mdelay(5);
     350             : 
     351             :         /* initialize UVD memory controller */
     352           0 :         WREG32(mmUVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
     353             :                              (1 << 21) | (1 << 9) | (1 << 20));
     354             : 
     355             : #ifdef __BIG_ENDIAN
     356             :         /* swap (8 in 32) RB and IB */
     357             :         lmi_swap_cntl = 0xa;
     358             :         mp_swap_cntl = 0;
     359             : #endif
     360           0 :         WREG32(mmUVD_LMI_SWAP_CNTL, lmi_swap_cntl);
     361           0 :         WREG32(mmUVD_MP_SWAP_CNTL, mp_swap_cntl);
     362             : 
     363           0 :         WREG32(mmUVD_MPC_SET_MUXA0, 0x40c2040);
     364           0 :         WREG32(mmUVD_MPC_SET_MUXA1, 0x0);
     365           0 :         WREG32(mmUVD_MPC_SET_MUXB0, 0x40c2040);
     366           0 :         WREG32(mmUVD_MPC_SET_MUXB1, 0x0);
     367           0 :         WREG32(mmUVD_MPC_SET_ALU, 0);
     368           0 :         WREG32(mmUVD_MPC_SET_MUX, 0x88);
     369             : 
     370             :         /* take all subblocks out of reset, except VCPU */
     371           0 :         WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     372           0 :         mdelay(5);
     373             : 
     374             :         /* enable VCPU clock */
     375           0 :         WREG32(mmUVD_VCPU_CNTL,  1 << 9);
     376             : 
     377             :         /* enable UMC */
     378           0 :         WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
     379             : 
     380             :         /* boot up the VCPU */
     381           0 :         WREG32(mmUVD_SOFT_RESET, 0);
     382           0 :         mdelay(10);
     383             : 
     384           0 :         for (i = 0; i < 10; ++i) {
     385             :                 uint32_t status;
     386           0 :                 for (j = 0; j < 100; ++j) {
     387           0 :                         status = RREG32(mmUVD_STATUS);
     388           0 :                         if (status & 2)
     389             :                                 break;
     390           0 :                         mdelay(10);
     391             :                 }
     392           0 :                 r = 0;
     393           0 :                 if (status & 2)
     394             :                         break;
     395             : 
     396           0 :                 DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
     397           0 :                 WREG32_P(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK,
     398             :                                 ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     399           0 :                 mdelay(10);
     400           0 :                 WREG32_P(mmUVD_SOFT_RESET, 0, ~UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     401           0 :                 mdelay(10);
     402           0 :                 r = -1;
     403             :         }
     404             : 
     405           0 :         if (r) {
     406           0 :                 DRM_ERROR("UVD not responding, giving up!!!\n");
     407           0 :                 return r;
     408             :         }
     409             :         /* enable master interrupt */
     410           0 :         WREG32_P(mmUVD_MASTINT_EN, 3 << 1, ~(3 << 1));
     411             : 
     412             :         /* clear the bit 4 of UVD_STATUS */
     413           0 :         WREG32_P(mmUVD_STATUS, 0, ~(2 << 1));
     414             : 
     415           0 :         rb_bufsz = order_base_2(ring->ring_size);
     416           0 :         tmp = 0;
     417           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
     418           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
     419           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
     420           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_WPTR_POLL_EN, 0);
     421           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
     422           0 :         tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
     423             :         /* force RBC into idle state */
     424           0 :         WREG32(mmUVD_RBC_RB_CNTL, tmp);
     425             : 
     426             :         /* set the write pointer delay */
     427           0 :         WREG32(mmUVD_RBC_RB_WPTR_CNTL, 0);
     428             : 
     429             :         /* set the wb address */
     430           0 :         WREG32(mmUVD_RBC_RB_RPTR_ADDR, (upper_32_bits(ring->gpu_addr) >> 2));
     431             : 
     432             :         /* program the RB_BASE for ring buffer */
     433           0 :         WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
     434             :                         lower_32_bits(ring->gpu_addr));
     435           0 :         WREG32(mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
     436             :                         upper_32_bits(ring->gpu_addr));
     437             : 
     438             :         /* Initialize the ring buffer's read and write pointers */
     439           0 :         WREG32(mmUVD_RBC_RB_RPTR, 0);
     440             : 
     441           0 :         ring->wptr = RREG32(mmUVD_RBC_RB_RPTR);
     442           0 :         WREG32(mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
     443             : 
     444           0 :         WREG32_P(mmUVD_RBC_RB_CNTL, 0, ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
     445             : 
     446           0 :         return 0;
     447             : }
     448             : 
     449             : /**
     450             :  * uvd_v5_0_stop - stop UVD block
     451             :  *
     452             :  * @adev: amdgpu_device pointer
     453             :  *
     454             :  * stop the UVD block
     455             :  */
     456           0 : static void uvd_v5_0_stop(struct amdgpu_device *adev)
     457             : {
     458             :         /* force RBC into idle state */
     459           0 :         WREG32(mmUVD_RBC_RB_CNTL, 0x11010101);
     460             : 
     461             :         /* Stall UMC and register bus before resetting VCPU */
     462           0 :         WREG32_P(mmUVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
     463           0 :         mdelay(1);
     464             : 
     465             :         /* put VCPU into reset */
     466           0 :         WREG32(mmUVD_SOFT_RESET, UVD_SOFT_RESET__VCPU_SOFT_RESET_MASK);
     467           0 :         mdelay(5);
     468             : 
     469             :         /* disable VCPU clock */
     470           0 :         WREG32(mmUVD_VCPU_CNTL, 0x0);
     471             : 
     472             :         /* Unstall UMC and register bus */
     473           0 :         WREG32_P(mmUVD_LMI_CTRL2, 0, ~(1 << 8));
     474             : 
     475           0 :         WREG32(mmUVD_STATUS, 0);
     476           0 : }
     477             : 
     478             : /**
     479             :  * uvd_v5_0_ring_emit_fence - emit an fence & trap command
     480             :  *
     481             :  * @ring: amdgpu_ring pointer
     482             :  * @addr: address
     483             :  * @seq: sequence number
     484             :  * @flags: fence related flags
     485             :  *
     486             :  * Write a fence and a trap command to the ring.
     487             :  */
     488           0 : static void uvd_v5_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
     489             :                                      unsigned flags)
     490             : {
     491           0 :         WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
     492             : 
     493           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0));
     494           0 :         amdgpu_ring_write(ring, seq);
     495           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
     496           0 :         amdgpu_ring_write(ring, addr & 0xffffffff);
     497           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
     498           0 :         amdgpu_ring_write(ring, upper_32_bits(addr) & 0xff);
     499           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
     500           0 :         amdgpu_ring_write(ring, 0);
     501             : 
     502           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
     503           0 :         amdgpu_ring_write(ring, 0);
     504           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
     505           0 :         amdgpu_ring_write(ring, 0);
     506           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
     507           0 :         amdgpu_ring_write(ring, 2);
     508           0 : }
     509             : 
     510             : /**
     511             :  * uvd_v5_0_ring_test_ring - register write test
     512             :  *
     513             :  * @ring: amdgpu_ring pointer
     514             :  *
     515             :  * Test if we can successfully write to the context register
     516             :  */
     517           0 : static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring)
     518             : {
     519           0 :         struct amdgpu_device *adev = ring->adev;
     520           0 :         uint32_t tmp = 0;
     521             :         unsigned i;
     522             :         int r;
     523             : 
     524           0 :         WREG32(mmUVD_CONTEXT_ID, 0xCAFEDEAD);
     525           0 :         r = amdgpu_ring_alloc(ring, 3);
     526           0 :         if (r)
     527             :                 return r;
     528           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_CONTEXT_ID, 0));
     529           0 :         amdgpu_ring_write(ring, 0xDEADBEEF);
     530           0 :         amdgpu_ring_commit(ring);
     531           0 :         for (i = 0; i < adev->usec_timeout; i++) {
     532           0 :                 tmp = RREG32(mmUVD_CONTEXT_ID);
     533           0 :                 if (tmp == 0xDEADBEEF)
     534             :                         break;
     535           0 :                 udelay(1);
     536             :         }
     537             : 
     538           0 :         if (i >= adev->usec_timeout)
     539           0 :                 r = -ETIMEDOUT;
     540             : 
     541             :         return r;
     542             : }
     543             : 
     544             : /**
     545             :  * uvd_v5_0_ring_emit_ib - execute indirect buffer
     546             :  *
     547             :  * @ring: amdgpu_ring pointer
     548             :  * @job: job to retrieve vmid from
     549             :  * @ib: indirect buffer to execute
     550             :  * @flags: unused
     551             :  *
     552             :  * Write ring commands to execute the indirect buffer
     553             :  */
     554           0 : static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
     555             :                                   struct amdgpu_job *job,
     556             :                                   struct amdgpu_ib *ib,
     557             :                                   uint32_t flags)
     558             : {
     559           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW, 0));
     560           0 :         amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
     561           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH, 0));
     562           0 :         amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
     563           0 :         amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_SIZE, 0));
     564           0 :         amdgpu_ring_write(ring, ib->length_dw);
     565           0 : }
     566             : 
     567           0 : static void uvd_v5_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
     568             : {
     569             :         int i;
     570             : 
     571           0 :         WARN_ON(ring->wptr % 2 || count % 2);
     572             : 
     573           0 :         for (i = 0; i < count / 2; i++) {
     574           0 :                 amdgpu_ring_write(ring, PACKET0(mmUVD_NO_OP, 0));
     575           0 :                 amdgpu_ring_write(ring, 0);
     576             :         }
     577           0 : }
     578             : 
     579           0 : static bool uvd_v5_0_is_idle(void *handle)
     580             : {
     581           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     582             : 
     583           0 :         return !(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK);
     584             : }
     585             : 
     586           0 : static int uvd_v5_0_wait_for_idle(void *handle)
     587             : {
     588             :         unsigned i;
     589           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     590             : 
     591           0 :         for (i = 0; i < adev->usec_timeout; i++) {
     592           0 :                 if (!(RREG32(mmSRBM_STATUS) & SRBM_STATUS__UVD_BUSY_MASK))
     593             :                         return 0;
     594             :         }
     595             :         return -ETIMEDOUT;
     596             : }
     597             : 
     598           0 : static int uvd_v5_0_soft_reset(void *handle)
     599             : {
     600           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     601             : 
     602           0 :         uvd_v5_0_stop(adev);
     603             : 
     604           0 :         WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK,
     605             :                         ~SRBM_SOFT_RESET__SOFT_RESET_UVD_MASK);
     606           0 :         mdelay(5);
     607             : 
     608           0 :         return uvd_v5_0_start(adev);
     609             : }
     610             : 
     611           0 : static int uvd_v5_0_set_interrupt_state(struct amdgpu_device *adev,
     612             :                                         struct amdgpu_irq_src *source,
     613             :                                         unsigned type,
     614             :                                         enum amdgpu_interrupt_state state)
     615             : {
     616             :         // TODO
     617           0 :         return 0;
     618             : }
     619             : 
     620           0 : static int uvd_v5_0_process_interrupt(struct amdgpu_device *adev,
     621             :                                       struct amdgpu_irq_src *source,
     622             :                                       struct amdgpu_iv_entry *entry)
     623             : {
     624           0 :         DRM_DEBUG("IH: UVD TRAP\n");
     625           0 :         amdgpu_fence_process(&adev->uvd.inst->ring);
     626           0 :         return 0;
     627             : }
     628             : 
     629           0 : static void uvd_v5_0_enable_clock_gating(struct amdgpu_device *adev, bool enable)
     630             : {
     631             :         uint32_t data1, data3, suvd_flags;
     632             : 
     633           0 :         data1 = RREG32(mmUVD_SUVD_CGC_GATE);
     634           0 :         data3 = RREG32(mmUVD_CGC_GATE);
     635             : 
     636           0 :         suvd_flags = UVD_SUVD_CGC_GATE__SRE_MASK |
     637             :                      UVD_SUVD_CGC_GATE__SIT_MASK |
     638             :                      UVD_SUVD_CGC_GATE__SMP_MASK |
     639             :                      UVD_SUVD_CGC_GATE__SCM_MASK |
     640             :                      UVD_SUVD_CGC_GATE__SDB_MASK;
     641             : 
     642           0 :         if (enable) {
     643           0 :                 data3 |= (UVD_CGC_GATE__SYS_MASK     |
     644             :                         UVD_CGC_GATE__UDEC_MASK      |
     645             :                         UVD_CGC_GATE__MPEG2_MASK     |
     646             :                         UVD_CGC_GATE__RBC_MASK       |
     647             :                         UVD_CGC_GATE__LMI_MC_MASK    |
     648             :                         UVD_CGC_GATE__IDCT_MASK      |
     649             :                         UVD_CGC_GATE__MPRD_MASK      |
     650             :                         UVD_CGC_GATE__MPC_MASK       |
     651             :                         UVD_CGC_GATE__LBSI_MASK      |
     652             :                         UVD_CGC_GATE__LRBBM_MASK     |
     653             :                         UVD_CGC_GATE__UDEC_RE_MASK   |
     654             :                         UVD_CGC_GATE__UDEC_CM_MASK   |
     655             :                         UVD_CGC_GATE__UDEC_IT_MASK   |
     656             :                         UVD_CGC_GATE__UDEC_DB_MASK   |
     657             :                         UVD_CGC_GATE__UDEC_MP_MASK   |
     658             :                         UVD_CGC_GATE__WCB_MASK       |
     659             :                         UVD_CGC_GATE__JPEG_MASK      |
     660             :                         UVD_CGC_GATE__SCPU_MASK);
     661             :                 /* only in pg enabled, we can gate clock to vcpu*/
     662           0 :                 if (adev->pg_flags & AMD_PG_SUPPORT_UVD)
     663           0 :                         data3 |= UVD_CGC_GATE__VCPU_MASK;
     664           0 :                 data3 &= ~UVD_CGC_GATE__REGS_MASK;
     665           0 :                 data1 |= suvd_flags;
     666             :         } else {
     667             :                 data3 = 0;
     668             :                 data1 = 0;
     669             :         }
     670             : 
     671           0 :         WREG32(mmUVD_SUVD_CGC_GATE, data1);
     672           0 :         WREG32(mmUVD_CGC_GATE, data3);
     673           0 : }
     674             : 
     675           0 : static void uvd_v5_0_set_sw_clock_gating(struct amdgpu_device *adev)
     676             : {
     677             :         uint32_t data, data2;
     678             : 
     679           0 :         data = RREG32(mmUVD_CGC_CTRL);
     680           0 :         data2 = RREG32(mmUVD_SUVD_CGC_CTRL);
     681             : 
     682             : 
     683           0 :         data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK |
     684             :                   UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK);
     685             : 
     686             : 
     687           0 :         data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK |
     688             :                 (1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_GATE_DLY_TIMER)) |
     689             :                 (4 << REG_FIELD_SHIFT(UVD_CGC_CTRL, CLK_OFF_DELAY));
     690             : 
     691           0 :         data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
     692             :                         UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
     693             :                         UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
     694             :                         UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
     695             :                         UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
     696             :                         UVD_CGC_CTRL__SYS_MODE_MASK |
     697             :                         UVD_CGC_CTRL__UDEC_MODE_MASK |
     698             :                         UVD_CGC_CTRL__MPEG2_MODE_MASK |
     699             :                         UVD_CGC_CTRL__REGS_MODE_MASK |
     700             :                         UVD_CGC_CTRL__RBC_MODE_MASK |
     701             :                         UVD_CGC_CTRL__LMI_MC_MODE_MASK |
     702             :                         UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
     703             :                         UVD_CGC_CTRL__IDCT_MODE_MASK |
     704             :                         UVD_CGC_CTRL__MPRD_MODE_MASK |
     705             :                         UVD_CGC_CTRL__MPC_MODE_MASK |
     706             :                         UVD_CGC_CTRL__LBSI_MODE_MASK |
     707             :                         UVD_CGC_CTRL__LRBBM_MODE_MASK |
     708             :                         UVD_CGC_CTRL__WCB_MODE_MASK |
     709             :                         UVD_CGC_CTRL__VCPU_MODE_MASK |
     710             :                         UVD_CGC_CTRL__JPEG_MODE_MASK |
     711             :                         UVD_CGC_CTRL__SCPU_MODE_MASK);
     712           0 :         data2 &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK |
     713             :                         UVD_SUVD_CGC_CTRL__SIT_MODE_MASK |
     714             :                         UVD_SUVD_CGC_CTRL__SMP_MODE_MASK |
     715             :                         UVD_SUVD_CGC_CTRL__SCM_MODE_MASK |
     716             :                         UVD_SUVD_CGC_CTRL__SDB_MODE_MASK);
     717             : 
     718           0 :         WREG32(mmUVD_CGC_CTRL, data);
     719           0 :         WREG32(mmUVD_SUVD_CGC_CTRL, data2);
     720           0 : }
     721             : 
     722             : #if 0
     723             : static void uvd_v5_0_set_hw_clock_gating(struct amdgpu_device *adev)
     724             : {
     725             :         uint32_t data, data1, cgc_flags, suvd_flags;
     726             : 
     727             :         data = RREG32(mmUVD_CGC_GATE);
     728             :         data1 = RREG32(mmUVD_SUVD_CGC_GATE);
     729             : 
     730             :         cgc_flags = UVD_CGC_GATE__SYS_MASK |
     731             :                                 UVD_CGC_GATE__UDEC_MASK |
     732             :                                 UVD_CGC_GATE__MPEG2_MASK |
     733             :                                 UVD_CGC_GATE__RBC_MASK |
     734             :                                 UVD_CGC_GATE__LMI_MC_MASK |
     735             :                                 UVD_CGC_GATE__IDCT_MASK |
     736             :                                 UVD_CGC_GATE__MPRD_MASK |
     737             :                                 UVD_CGC_GATE__MPC_MASK |
     738             :                                 UVD_CGC_GATE__LBSI_MASK |
     739             :                                 UVD_CGC_GATE__LRBBM_MASK |
     740             :                                 UVD_CGC_GATE__UDEC_RE_MASK |
     741             :                                 UVD_CGC_GATE__UDEC_CM_MASK |
     742             :                                 UVD_CGC_GATE__UDEC_IT_MASK |
     743             :                                 UVD_CGC_GATE__UDEC_DB_MASK |
     744             :                                 UVD_CGC_GATE__UDEC_MP_MASK |
     745             :                                 UVD_CGC_GATE__WCB_MASK |
     746             :                                 UVD_CGC_GATE__VCPU_MASK |
     747             :                                 UVD_CGC_GATE__SCPU_MASK;
     748             : 
     749             :         suvd_flags = UVD_SUVD_CGC_GATE__SRE_MASK |
     750             :                                 UVD_SUVD_CGC_GATE__SIT_MASK |
     751             :                                 UVD_SUVD_CGC_GATE__SMP_MASK |
     752             :                                 UVD_SUVD_CGC_GATE__SCM_MASK |
     753             :                                 UVD_SUVD_CGC_GATE__SDB_MASK;
     754             : 
     755             :         data |= cgc_flags;
     756             :         data1 |= suvd_flags;
     757             : 
     758             :         WREG32(mmUVD_CGC_GATE, data);
     759             :         WREG32(mmUVD_SUVD_CGC_GATE, data1);
     760             : }
     761             : #endif
     762             : 
     763           0 : static void uvd_v5_0_enable_mgcg(struct amdgpu_device *adev,
     764             :                                  bool enable)
     765             : {
     766             :         u32 orig, data;
     767             : 
     768           0 :         if (enable && (adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) {
     769           0 :                 data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL);
     770           0 :                 data |= 0xfff;
     771           0 :                 WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data);
     772             : 
     773           0 :                 orig = data = RREG32(mmUVD_CGC_CTRL);
     774           0 :                 data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
     775           0 :                 if (orig != data)
     776           0 :                         WREG32(mmUVD_CGC_CTRL, data);
     777             :         } else {
     778           0 :                 data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL);
     779           0 :                 data &= ~0xfff;
     780           0 :                 WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data);
     781             : 
     782           0 :                 orig = data = RREG32(mmUVD_CGC_CTRL);
     783           0 :                 data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
     784           0 :                 if (orig != data)
     785           0 :                         WREG32(mmUVD_CGC_CTRL, data);
     786             :         }
     787           0 : }
     788             : 
     789           0 : static int uvd_v5_0_set_clockgating_state(void *handle,
     790             :                                           enum amd_clockgating_state state)
     791             : {
     792           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     793           0 :         bool enable = (state == AMD_CG_STATE_GATE);
     794             : 
     795           0 :         if (enable) {
     796             :                 /* wait for STATUS to clear */
     797           0 :                 if (uvd_v5_0_wait_for_idle(handle))
     798             :                         return -EBUSY;
     799           0 :                 uvd_v5_0_enable_clock_gating(adev, true);
     800             : 
     801             :                 /* enable HW gates because UVD is idle */
     802             : /*              uvd_v5_0_set_hw_clock_gating(adev); */
     803             :         } else {
     804           0 :                 uvd_v5_0_enable_clock_gating(adev, false);
     805             :         }
     806             : 
     807           0 :         uvd_v5_0_set_sw_clock_gating(adev);
     808           0 :         return 0;
     809             : }
     810             : 
     811           0 : static int uvd_v5_0_set_powergating_state(void *handle,
     812             :                                           enum amd_powergating_state state)
     813             : {
     814             :         /* This doesn't actually powergate the UVD block.
     815             :          * That's done in the dpm code via the SMC.  This
     816             :          * just re-inits the block as necessary.  The actual
     817             :          * gating still happens in the dpm code.  We should
     818             :          * revisit this when there is a cleaner line between
     819             :          * the smc and the hw blocks
     820             :          */
     821           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     822           0 :         int ret = 0;
     823             : 
     824           0 :         if (state == AMD_PG_STATE_GATE) {
     825           0 :                 uvd_v5_0_stop(adev);
     826             :         } else {
     827           0 :                 ret = uvd_v5_0_start(adev);
     828             :                 if (ret)
     829             :                         goto out;
     830             :         }
     831             : 
     832             : out:
     833           0 :         return ret;
     834             : }
     835             : 
     836           0 : static void uvd_v5_0_get_clockgating_state(void *handle, u64 *flags)
     837             : {
     838           0 :         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
     839             :         int data;
     840             : 
     841           0 :         mutex_lock(&adev->pm.mutex);
     842             : 
     843           0 :         if (RREG32_SMC(ixCURRENT_PG_STATUS) &
     844             :                                 CURRENT_PG_STATUS__UVD_PG_STATUS_MASK) {
     845           0 :                 DRM_INFO("Cannot get clockgating state when UVD is powergated.\n");
     846           0 :                 goto out;
     847             :         }
     848             : 
     849             :         /* AMD_CG_SUPPORT_UVD_MGCG */
     850           0 :         data = RREG32(mmUVD_CGC_CTRL);
     851           0 :         if (data & UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK)
     852           0 :                 *flags |= AMD_CG_SUPPORT_UVD_MGCG;
     853             : 
     854             : out:
     855           0 :         mutex_unlock(&adev->pm.mutex);
     856           0 : }
     857             : 
     858             : static const struct amd_ip_funcs uvd_v5_0_ip_funcs = {
     859             :         .name = "uvd_v5_0",
     860             :         .early_init = uvd_v5_0_early_init,
     861             :         .late_init = NULL,
     862             :         .sw_init = uvd_v5_0_sw_init,
     863             :         .sw_fini = uvd_v5_0_sw_fini,
     864             :         .hw_init = uvd_v5_0_hw_init,
     865             :         .hw_fini = uvd_v5_0_hw_fini,
     866             :         .suspend = uvd_v5_0_suspend,
     867             :         .resume = uvd_v5_0_resume,
     868             :         .is_idle = uvd_v5_0_is_idle,
     869             :         .wait_for_idle = uvd_v5_0_wait_for_idle,
     870             :         .soft_reset = uvd_v5_0_soft_reset,
     871             :         .set_clockgating_state = uvd_v5_0_set_clockgating_state,
     872             :         .set_powergating_state = uvd_v5_0_set_powergating_state,
     873             :         .get_clockgating_state = uvd_v5_0_get_clockgating_state,
     874             : };
     875             : 
     876             : static const struct amdgpu_ring_funcs uvd_v5_0_ring_funcs = {
     877             :         .type = AMDGPU_RING_TYPE_UVD,
     878             :         .align_mask = 0xf,
     879             :         .support_64bit_ptrs = false,
     880             :         .no_user_fence = true,
     881             :         .get_rptr = uvd_v5_0_ring_get_rptr,
     882             :         .get_wptr = uvd_v5_0_ring_get_wptr,
     883             :         .set_wptr = uvd_v5_0_ring_set_wptr,
     884             :         .parse_cs = amdgpu_uvd_ring_parse_cs,
     885             :         .emit_frame_size =
     886             :                 14, /* uvd_v5_0_ring_emit_fence  x1 no user fence */
     887             :         .emit_ib_size = 6, /* uvd_v5_0_ring_emit_ib */
     888             :         .emit_ib = uvd_v5_0_ring_emit_ib,
     889             :         .emit_fence = uvd_v5_0_ring_emit_fence,
     890             :         .test_ring = uvd_v5_0_ring_test_ring,
     891             :         .test_ib = amdgpu_uvd_ring_test_ib,
     892             :         .insert_nop = uvd_v5_0_ring_insert_nop,
     893             :         .pad_ib = amdgpu_ring_generic_pad_ib,
     894             :         .begin_use = amdgpu_uvd_ring_begin_use,
     895             :         .end_use = amdgpu_uvd_ring_end_use,
     896             : };
     897             : 
     898             : static void uvd_v5_0_set_ring_funcs(struct amdgpu_device *adev)
     899             : {
     900           0 :         adev->uvd.inst->ring.funcs = &uvd_v5_0_ring_funcs;
     901             : }
     902             : 
     903             : static const struct amdgpu_irq_src_funcs uvd_v5_0_irq_funcs = {
     904             :         .set = uvd_v5_0_set_interrupt_state,
     905             :         .process = uvd_v5_0_process_interrupt,
     906             : };
     907             : 
     908             : static void uvd_v5_0_set_irq_funcs(struct amdgpu_device *adev)
     909             : {
     910           0 :         adev->uvd.inst->irq.num_types = 1;
     911           0 :         adev->uvd.inst->irq.funcs = &uvd_v5_0_irq_funcs;
     912             : }
     913             : 
     914             : const struct amdgpu_ip_block_version uvd_v5_0_ip_block =
     915             : {
     916             :                 .type = AMD_IP_BLOCK_TYPE_UVD,
     917             :                 .major = 5,
     918             :                 .minor = 0,
     919             :                 .rev = 0,
     920             :                 .funcs = &uvd_v5_0_ip_funcs,
     921             : };

Generated by: LCOV version 1.14