root/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vcn_v2_5_early_init
  2. vcn_v2_5_sw_init
  3. vcn_v2_5_sw_fini
  4. vcn_v2_5_hw_init
  5. vcn_v2_5_hw_fini
  6. vcn_v2_5_suspend
  7. vcn_v2_5_resume
  8. vcn_v2_5_mc_resume
  9. vcn_v2_5_disable_clock_gating
  10. vcn_v2_5_enable_clock_gating
  11. jpeg_v2_5_start
  12. jpeg_v2_5_stop
  13. vcn_v2_5_start
  14. vcn_v2_5_stop
  15. vcn_v2_5_dec_ring_get_rptr
  16. vcn_v2_5_dec_ring_get_wptr
  17. vcn_v2_5_dec_ring_set_wptr
  18. vcn_v2_5_enc_ring_get_rptr
  19. vcn_v2_5_enc_ring_get_wptr
  20. vcn_v2_5_enc_ring_set_wptr
  21. vcn_v2_5_jpeg_ring_get_rptr
  22. vcn_v2_5_jpeg_ring_get_wptr
  23. vcn_v2_5_jpeg_ring_set_wptr
  24. vcn_v2_5_set_dec_ring_funcs
  25. vcn_v2_5_set_enc_ring_funcs
  26. vcn_v2_5_set_jpeg_ring_funcs
  27. vcn_v2_5_is_idle
  28. vcn_v2_5_wait_for_idle
  29. vcn_v2_5_set_clockgating_state
  30. vcn_v2_5_set_powergating_state
  31. vcn_v2_5_set_interrupt_state
  32. vcn_v2_5_process_interrupt
  33. vcn_v2_5_set_irq_funcs

   1 /*
   2  * Copyright 2019 Advanced Micro Devices, Inc.
   3  *
   4  * Permission is hereby granted, free of charge, to any person obtaining a
   5  * copy of this software and associated documentation files (the "Software"),
   6  * to deal in the Software without restriction, including without limitation
   7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8  * and/or sell copies of the Software, and to permit persons to whom the
   9  * Software is furnished to do so, subject to the following conditions:
  10  *
  11  * The above copyright notice and this permission notice shall be included in
  12  * all copies or substantial portions of the Software.
  13  *
  14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20  * OTHER DEALINGS IN THE SOFTWARE.
  21  *
  22  */
  23 
  24 #include <linux/firmware.h>
  25 
  26 #include "amdgpu.h"
  27 #include "amdgpu_vcn.h"
  28 #include "soc15.h"
  29 #include "soc15d.h"
  30 #include "vcn_v2_0.h"
  31 
  32 #include "vcn/vcn_2_5_offset.h"
  33 #include "vcn/vcn_2_5_sh_mask.h"
  34 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
  35 
  36 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET                        0x27
  37 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET                    0x0f
  38 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET                  0x10
  39 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET                  0x11
  40 #define mmUVD_NO_OP_INTERNAL_OFFSET                             0x29
  41 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET                       0x66
  42 #define mmUVD_SCRATCH9_INTERNAL_OFFSET                          0xc01d
  43 
  44 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET                   0x431
  45 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET          0x3b4
  46 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET         0x3b5
  47 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET                       0x25c
  48 
  49 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET                        0x401f
  50 
  51 #define VCN25_MAX_HW_INSTANCES_ARCTURUS                         2
  52 
  53 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
  54 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
  55 static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev);
  56 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
  57 static int vcn_v2_5_set_powergating_state(void *handle,
  58                                 enum amd_powergating_state state);
  59 
  60 static int amdgpu_ih_clientid_vcns[] = {
  61         SOC15_IH_CLIENTID_VCN,
  62         SOC15_IH_CLIENTID_VCN1
  63 };
  64 
  65 /**
  66  * vcn_v2_5_early_init - set function pointers
  67  *
  68  * @handle: amdgpu_device pointer
  69  *
  70  * Set ring and irq function pointers
  71  */
  72 static int vcn_v2_5_early_init(void *handle)
  73 {
  74         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  75         if (adev->asic_type == CHIP_ARCTURUS) {
  76                 u32 harvest;
  77                 int i;
  78 
  79                 adev->vcn.num_vcn_inst = VCN25_MAX_HW_INSTANCES_ARCTURUS;
  80                 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
  81                         harvest = RREG32_SOC15(UVD, i, mmCC_UVD_HARVESTING);
  82                         if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
  83                                 adev->vcn.harvest_config |= 1 << i;
  84                 }
  85 
  86                 if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
  87                                                  AMDGPU_VCN_HARVEST_VCN1))
  88                         /* both instances are harvested, disable the block */
  89                         return -ENOENT;
  90         } else
  91                 adev->vcn.num_vcn_inst = 1;
  92 
  93         adev->vcn.num_enc_rings = 2;
  94 
  95         vcn_v2_5_set_dec_ring_funcs(adev);
  96         vcn_v2_5_set_enc_ring_funcs(adev);
  97         vcn_v2_5_set_jpeg_ring_funcs(adev);
  98         vcn_v2_5_set_irq_funcs(adev);
  99 
 100         return 0;
 101 }
 102 
 103 /**
 104  * vcn_v2_5_sw_init - sw init for VCN block
 105  *
 106  * @handle: amdgpu_device pointer
 107  *
 108  * Load firmware and sw initialization
 109  */
 110 static int vcn_v2_5_sw_init(void *handle)
 111 {
 112         struct amdgpu_ring *ring;
 113         int i, j, r;
 114         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 115 
 116         for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
 117                 if (adev->vcn.harvest_config & (1 << j))
 118                         continue;
 119                 /* VCN DEC TRAP */
 120                 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 121                                 VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
 122                 if (r)
 123                         return r;
 124 
 125                 /* VCN ENC TRAP */
 126                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 127                         r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 128                                 i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
 129                         if (r)
 130                                 return r;
 131                 }
 132 
 133                 /* VCN JPEG TRAP */
 134                 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
 135                                 VCN_2_0__SRCID__JPEG_DECODE, &adev->vcn.inst[j].irq);
 136                 if (r)
 137                         return r;
 138         }
 139 
 140         r = amdgpu_vcn_sw_init(adev);
 141         if (r)
 142                 return r;
 143 
 144         if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
 145                 const struct common_firmware_header *hdr;
 146                 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
 147                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
 148                 adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
 149                 adev->firmware.fw_size +=
 150                         ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
 151 
 152                 if (adev->vcn.num_vcn_inst == VCN25_MAX_HW_INSTANCES_ARCTURUS) {
 153                         adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
 154                         adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
 155                         adev->firmware.fw_size +=
 156                                 ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
 157                 }
 158                 DRM_INFO("PSP loading VCN firmware\n");
 159         }
 160 
 161         r = amdgpu_vcn_resume(adev);
 162         if (r)
 163                 return r;
 164 
 165         for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
 166                 if (adev->vcn.harvest_config & (1 << j))
 167                         continue;
 168                 adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
 169                 adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
 170                 adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
 171                 adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
 172                 adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
 173                 adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
 174 
 175                 adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
 176                 adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(UVD, j, mmUVD_SCRATCH9);
 177                 adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
 178                 adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA0);
 179                 adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
 180                 adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA1);
 181                 adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
 182                 adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_CMD);
 183                 adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
 184                 adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(UVD, j, mmUVD_NO_OP);
 185 
 186                 adev->vcn.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
 187                 adev->vcn.inst[j].external.jpeg_pitch = SOC15_REG_OFFSET(UVD, j, mmUVD_JPEG_PITCH);
 188 
 189                 ring = &adev->vcn.inst[j].ring_dec;
 190                 ring->use_doorbell = true;
 191                 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8*j;
 192                 sprintf(ring->name, "vcn_dec_%d", j);
 193                 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
 194                 if (r)
 195                         return r;
 196 
 197                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 198                         ring = &adev->vcn.inst[j].ring_enc[i];
 199                         ring->use_doorbell = true;
 200                         ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i + 8*j;
 201                         sprintf(ring->name, "vcn_enc_%d.%d", j, i);
 202                         r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
 203                         if (r)
 204                                 return r;
 205                 }
 206 
 207                 ring = &adev->vcn.inst[j].ring_jpeg;
 208                 ring->use_doorbell = true;
 209                 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8*j;
 210                 sprintf(ring->name, "vcn_jpeg_%d", j);
 211                 r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
 212                 if (r)
 213                         return r;
 214         }
 215 
 216         return 0;
 217 }
 218 
 219 /**
 220  * vcn_v2_5_sw_fini - sw fini for VCN block
 221  *
 222  * @handle: amdgpu_device pointer
 223  *
 224  * VCN suspend and free up sw allocation
 225  */
 226 static int vcn_v2_5_sw_fini(void *handle)
 227 {
 228         int r;
 229         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 230 
 231         r = amdgpu_vcn_suspend(adev);
 232         if (r)
 233                 return r;
 234 
 235         r = amdgpu_vcn_sw_fini(adev);
 236 
 237         return r;
 238 }
 239 
 240 /**
 241  * vcn_v2_5_hw_init - start and test VCN block
 242  *
 243  * @handle: amdgpu_device pointer
 244  *
 245  * Initialize the hardware, boot up the VCPU and do some testing
 246  */
 247 static int vcn_v2_5_hw_init(void *handle)
 248 {
 249         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 250         struct amdgpu_ring *ring;
 251         int i, j, r;
 252 
 253         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
 254                 if (adev->vcn.harvest_config & (1 << j))
 255                         continue;
 256                 ring = &adev->vcn.inst[j].ring_dec;
 257 
 258                 adev->nbio_funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 259                                                      ring->doorbell_index, j);
 260 
 261                 r = amdgpu_ring_test_ring(ring);
 262                 if (r) {
 263                         ring->sched.ready = false;
 264                         goto done;
 265                 }
 266 
 267                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 268                         ring = &adev->vcn.inst[j].ring_enc[i];
 269                         ring->sched.ready = false;
 270                         continue;
 271                         r = amdgpu_ring_test_ring(ring);
 272                         if (r) {
 273                                 ring->sched.ready = false;
 274                                 goto done;
 275                         }
 276                 }
 277 
 278                 ring = &adev->vcn.inst[j].ring_jpeg;
 279                 r = amdgpu_ring_test_ring(ring);
 280                 if (r) {
 281                         ring->sched.ready = false;
 282                         goto done;
 283                 }
 284         }
 285 done:
 286         if (!r)
 287                 DRM_INFO("VCN decode and encode initialized successfully.\n");
 288 
 289         return r;
 290 }
 291 
 292 /**
 293  * vcn_v2_5_hw_fini - stop the hardware block
 294  *
 295  * @handle: amdgpu_device pointer
 296  *
 297  * Stop the VCN block, mark ring as not ready any more
 298  */
 299 static int vcn_v2_5_hw_fini(void *handle)
 300 {
 301         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 302         struct amdgpu_ring *ring;
 303         int i;
 304 
 305         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 306                 if (adev->vcn.harvest_config & (1 << i))
 307                         continue;
 308                 ring = &adev->vcn.inst[i].ring_dec;
 309 
 310                 if (RREG32_SOC15(VCN, i, mmUVD_STATUS))
 311                         vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
 312 
 313                 ring->sched.ready = false;
 314 
 315                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 316                         ring = &adev->vcn.inst[i].ring_enc[i];
 317                         ring->sched.ready = false;
 318                 }
 319 
 320                 ring = &adev->vcn.inst[i].ring_jpeg;
 321                 ring->sched.ready = false;
 322         }
 323 
 324         return 0;
 325 }
 326 
 327 /**
 328  * vcn_v2_5_suspend - suspend VCN block
 329  *
 330  * @handle: amdgpu_device pointer
 331  *
 332  * HW fini and suspend VCN block
 333  */
 334 static int vcn_v2_5_suspend(void *handle)
 335 {
 336         int r;
 337         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 338 
 339         r = vcn_v2_5_hw_fini(adev);
 340         if (r)
 341                 return r;
 342 
 343         r = amdgpu_vcn_suspend(adev);
 344 
 345         return r;
 346 }
 347 
 348 /**
 349  * vcn_v2_5_resume - resume VCN block
 350  *
 351  * @handle: amdgpu_device pointer
 352  *
 353  * Resume firmware and hw init VCN block
 354  */
 355 static int vcn_v2_5_resume(void *handle)
 356 {
 357         int r;
 358         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 359 
 360         r = amdgpu_vcn_resume(adev);
 361         if (r)
 362                 return r;
 363 
 364         r = vcn_v2_5_hw_init(adev);
 365 
 366         return r;
 367 }
 368 
 369 /**
 370  * vcn_v2_5_mc_resume - memory controller programming
 371  *
 372  * @adev: amdgpu_device pointer
 373  *
 374  * Let the VCN memory controller know it's offsets
 375  */
 376 static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
 377 {
 378         uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
 379         uint32_t offset;
 380         int i;
 381 
 382         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 383                 if (adev->vcn.harvest_config & (1 << i))
 384                         continue;
 385                 /* cache window 0: fw */
 386                 if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
 387                         WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
 388                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
 389                         WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
 390                                 (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
 391                         WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
 392                         offset = 0;
 393                 } else {
 394                         WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
 395                                 lower_32_bits(adev->vcn.inst[i].gpu_addr));
 396                         WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
 397                                 upper_32_bits(adev->vcn.inst[i].gpu_addr));
 398                         offset = size;
 399                         WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0,
 400                                 AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
 401                 }
 402                 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size);
 403 
 404                 /* cache window 1: stack */
 405                 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
 406                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
 407                 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
 408                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
 409                 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
 410                 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
 411 
 412                 /* cache window 2: context */
 413                 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
 414                         lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
 415                 WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
 416                         upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
 417                 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
 418                 WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
 419         }
 420 }
 421 
 422 /**
 423  * vcn_v2_5_disable_clock_gating - disable VCN clock gating
 424  *
 425  * @adev: amdgpu_device pointer
 426  *
 427  * Disable clock gating for VCN block
 428  */
 429 static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
 430 {
 431         uint32_t data;
 432         int ret = 0;
 433         int i;
 434 
 435         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 436                 if (adev->vcn.harvest_config & (1 << i))
 437                         continue;
 438                 /* UVD disable CGC */
 439                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
 440                 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
 441                         data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 442                 else
 443                         data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
 444                 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
 445                 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
 446                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
 447 
 448                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
 449                 data &= ~(UVD_CGC_GATE__SYS_MASK
 450                         | UVD_CGC_GATE__UDEC_MASK
 451                         | UVD_CGC_GATE__MPEG2_MASK
 452                         | UVD_CGC_GATE__REGS_MASK
 453                         | UVD_CGC_GATE__RBC_MASK
 454                         | UVD_CGC_GATE__LMI_MC_MASK
 455                         | UVD_CGC_GATE__LMI_UMC_MASK
 456                         | UVD_CGC_GATE__IDCT_MASK
 457                         | UVD_CGC_GATE__MPRD_MASK
 458                         | UVD_CGC_GATE__MPC_MASK
 459                         | UVD_CGC_GATE__LBSI_MASK
 460                         | UVD_CGC_GATE__LRBBM_MASK
 461                         | UVD_CGC_GATE__UDEC_RE_MASK
 462                         | UVD_CGC_GATE__UDEC_CM_MASK
 463                         | UVD_CGC_GATE__UDEC_IT_MASK
 464                         | UVD_CGC_GATE__UDEC_DB_MASK
 465                         | UVD_CGC_GATE__UDEC_MP_MASK
 466                         | UVD_CGC_GATE__WCB_MASK
 467                         | UVD_CGC_GATE__VCPU_MASK
 468                         | UVD_CGC_GATE__MMSCH_MASK);
 469 
 470                 WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
 471 
 472                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0,  0xFFFFFFFF, ret);
 473 
 474                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
 475                 data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
 476                         | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
 477                         | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
 478                         | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
 479                         | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
 480                         | UVD_CGC_CTRL__SYS_MODE_MASK
 481                         | UVD_CGC_CTRL__UDEC_MODE_MASK
 482                         | UVD_CGC_CTRL__MPEG2_MODE_MASK
 483                         | UVD_CGC_CTRL__REGS_MODE_MASK
 484                         | UVD_CGC_CTRL__RBC_MODE_MASK
 485                         | UVD_CGC_CTRL__LMI_MC_MODE_MASK
 486                         | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
 487                         | UVD_CGC_CTRL__IDCT_MODE_MASK
 488                         | UVD_CGC_CTRL__MPRD_MODE_MASK
 489                         | UVD_CGC_CTRL__MPC_MODE_MASK
 490                         | UVD_CGC_CTRL__LBSI_MODE_MASK
 491                         | UVD_CGC_CTRL__LRBBM_MODE_MASK
 492                         | UVD_CGC_CTRL__WCB_MODE_MASK
 493                         | UVD_CGC_CTRL__VCPU_MODE_MASK
 494                         | UVD_CGC_CTRL__MMSCH_MODE_MASK);
 495                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
 496 
 497                 /* turn on */
 498                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
 499                 data |= (UVD_SUVD_CGC_GATE__SRE_MASK
 500                         | UVD_SUVD_CGC_GATE__SIT_MASK
 501                         | UVD_SUVD_CGC_GATE__SMP_MASK
 502                         | UVD_SUVD_CGC_GATE__SCM_MASK
 503                         | UVD_SUVD_CGC_GATE__SDB_MASK
 504                         | UVD_SUVD_CGC_GATE__SRE_H264_MASK
 505                         | UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
 506                         | UVD_SUVD_CGC_GATE__SIT_H264_MASK
 507                         | UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
 508                         | UVD_SUVD_CGC_GATE__SCM_H264_MASK
 509                         | UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
 510                         | UVD_SUVD_CGC_GATE__SDB_H264_MASK
 511                         | UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
 512                         | UVD_SUVD_CGC_GATE__SCLR_MASK
 513                         | UVD_SUVD_CGC_GATE__UVD_SC_MASK
 514                         | UVD_SUVD_CGC_GATE__ENT_MASK
 515                         | UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
 516                         | UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
 517                         | UVD_SUVD_CGC_GATE__SITE_MASK
 518                         | UVD_SUVD_CGC_GATE__SRE_VP9_MASK
 519                         | UVD_SUVD_CGC_GATE__SCM_VP9_MASK
 520                         | UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
 521                         | UVD_SUVD_CGC_GATE__SDB_VP9_MASK
 522                         | UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
 523                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
 524 
 525                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
 526                 data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
 527                         | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
 528                         | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
 529                         | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
 530                         | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
 531                         | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
 532                         | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
 533                         | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
 534                         | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
 535                         | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
 536                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
 537         }
 538 }
 539 
 540 /**
 541  * vcn_v2_5_enable_clock_gating - enable VCN clock gating
 542  *
 543  * @adev: amdgpu_device pointer
 544  *
 545  * Enable clock gating for VCN block
 546  */
 547 static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
 548 {
 549         uint32_t data = 0;
 550         int i;
 551 
 552         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 553                 if (adev->vcn.harvest_config & (1 << i))
 554                         continue;
 555                 /* enable UVD CGC */
 556                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
 557                 if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
 558                         data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 559                 else
 560                         data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 561                 data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
 562                 data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
 563                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
 564 
 565                 data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
 566                 data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
 567                         | UVD_CGC_CTRL__UDEC_CM_MODE_MASK
 568                         | UVD_CGC_CTRL__UDEC_IT_MODE_MASK
 569                         | UVD_CGC_CTRL__UDEC_DB_MODE_MASK
 570                         | UVD_CGC_CTRL__UDEC_MP_MODE_MASK
 571                         | UVD_CGC_CTRL__SYS_MODE_MASK
 572                         | UVD_CGC_CTRL__UDEC_MODE_MASK
 573                         | UVD_CGC_CTRL__MPEG2_MODE_MASK
 574                         | UVD_CGC_CTRL__REGS_MODE_MASK
 575                         | UVD_CGC_CTRL__RBC_MODE_MASK
 576                         | UVD_CGC_CTRL__LMI_MC_MODE_MASK
 577                         | UVD_CGC_CTRL__LMI_UMC_MODE_MASK
 578                         | UVD_CGC_CTRL__IDCT_MODE_MASK
 579                         | UVD_CGC_CTRL__MPRD_MODE_MASK
 580                         | UVD_CGC_CTRL__MPC_MODE_MASK
 581                         | UVD_CGC_CTRL__LBSI_MODE_MASK
 582                         | UVD_CGC_CTRL__LRBBM_MODE_MASK
 583                         | UVD_CGC_CTRL__WCB_MODE_MASK
 584                         | UVD_CGC_CTRL__VCPU_MODE_MASK);
 585                 WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
 586 
 587                 data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
 588                 data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
 589                         | UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
 590                         | UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
 591                         | UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
 592                         | UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
 593                         | UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
 594                         | UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
 595                         | UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
 596                         | UVD_SUVD_CGC_CTRL__IME_MODE_MASK
 597                         | UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
 598                 WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
 599         }
 600 }
 601 
 602 /**
 603  * jpeg_v2_5_start - start JPEG block
 604  *
 605  * @adev: amdgpu_device pointer
 606  *
 607  * Setup and start the JPEG block
 608  */
 609 static int jpeg_v2_5_start(struct amdgpu_device *adev)
 610 {
 611         struct amdgpu_ring *ring;
 612         uint32_t tmp;
 613         int i;
 614 
 615         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 616                 if (adev->vcn.harvest_config & (1 << i))
 617                         continue;
 618                 ring = &adev->vcn.inst[i].ring_jpeg;
 619                 /* disable anti hang mechanism */
 620                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS), 0,
 621                         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
 622 
 623                 /* JPEG disable CGC */
 624                 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL);
 625                 tmp |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 626                 tmp |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
 627                 tmp |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
 628                 WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp);
 629 
 630                 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE);
 631                 tmp &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
 632                         | JPEG_CGC_GATE__JPEG2_DEC_MASK
 633                         | JPEG_CGC_GATE__JMCIF_MASK
 634                         | JPEG_CGC_GATE__JRBBM_MASK);
 635                 WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp);
 636 
 637                 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL);
 638                 tmp &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK
 639                         | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK
 640                         | JPEG_CGC_CTRL__JMCIF_MODE_MASK
 641                         | JPEG_CGC_CTRL__JRBBM_MODE_MASK);
 642                 WREG32_SOC15(VCN, i, mmJPEG_CGC_CTRL, tmp);
 643 
 644                 /* MJPEG global tiling registers */
 645                 WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
 646                         adev->gfx.config.gb_addr_config);
 647                 WREG32_SOC15(UVD, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
 648                         adev->gfx.config.gb_addr_config);
 649 
 650                 /* enable JMI channel */
 651                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL), 0,
 652                         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
 653 
 654                 /* enable System Interrupt for JRBC */
 655                 WREG32_P(SOC15_REG_OFFSET(VCN, i, mmJPEG_SYS_INT_EN),
 656                         JPEG_SYS_INT_EN__DJRBC_MASK,
 657                         ~JPEG_SYS_INT_EN__DJRBC_MASK);
 658 
 659                 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_VMID, 0);
 660                 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
 661                 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
 662                         lower_32_bits(ring->gpu_addr));
 663                 WREG32_SOC15(UVD, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
 664                         upper_32_bits(ring->gpu_addr));
 665                 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_RPTR, 0);
 666                 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR, 0);
 667                 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
 668                 WREG32_SOC15(UVD, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
 669                 ring->wptr = RREG32_SOC15(UVD, i, mmUVD_JRBC_RB_WPTR);
 670         }
 671 
 672         return 0;
 673 }
 674 
 675 /**
 676  * jpeg_v2_5_stop - stop JPEG block
 677  *
 678  * @adev: amdgpu_device pointer
 679  *
 680  * stop the JPEG block
 681  */
 682 static int jpeg_v2_5_stop(struct amdgpu_device *adev)
 683 {
 684         uint32_t tmp;
 685         int i;
 686 
 687         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 688                 if (adev->vcn.harvest_config & (1 << i))
 689                         continue;
 690                 /* reset JMI */
 691                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JMI_CNTL),
 692                         UVD_JMI_CNTL__SOFT_RESET_MASK,
 693                         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
 694 
 695                 tmp = RREG32_SOC15(VCN, i, mmJPEG_CGC_GATE);
 696                 tmp |= (JPEG_CGC_GATE__JPEG_DEC_MASK
 697                         |JPEG_CGC_GATE__JPEG2_DEC_MASK
 698                         |JPEG_CGC_GATE__JMCIF_MASK
 699                         |JPEG_CGC_GATE__JRBBM_MASK);
 700                 WREG32_SOC15(VCN, i, mmJPEG_CGC_GATE, tmp);
 701 
 702                 /* enable anti hang mechanism */
 703                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_JPEG_POWER_STATUS),
 704                         UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
 705                         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
 706         }
 707 
 708         return 0;
 709 }
 710 
 711 static int vcn_v2_5_start(struct amdgpu_device *adev)
 712 {
 713         struct amdgpu_ring *ring;
 714         uint32_t rb_bufsz, tmp;
 715         int i, j, k, r;
 716 
 717         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 718                 if (adev->vcn.harvest_config & (1 << i))
 719                         continue;
 720                 /* disable register anti-hang mechanism */
 721                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS), 0,
 722                         ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
 723 
 724                 /* set uvd status busy */
 725                 tmp = RREG32_SOC15(UVD, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
 726                 WREG32_SOC15(UVD, i, mmUVD_STATUS, tmp);
 727         }
 728 
 729         /*SW clock gating */
 730         vcn_v2_5_disable_clock_gating(adev);
 731 
 732         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 733                 if (adev->vcn.harvest_config & (1 << i))
 734                         continue;
 735                 /* enable VCPU clock */
 736                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
 737                         UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
 738 
 739                 /* disable master interrupt */
 740                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), 0,
 741                         ~UVD_MASTINT_EN__VCPU_EN_MASK);
 742 
 743                 /* setup mmUVD_LMI_CTRL */
 744                 tmp = RREG32_SOC15(UVD, i, mmUVD_LMI_CTRL);
 745                 tmp &= ~0xff;
 746                 WREG32_SOC15(UVD, i, mmUVD_LMI_CTRL, tmp | 0x8|
 747                         UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
 748                         UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
 749                         UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
 750                         UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
 751 
 752                 /* setup mmUVD_MPC_CNTL */
 753                 tmp = RREG32_SOC15(UVD, i, mmUVD_MPC_CNTL);
 754                 tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
 755                 tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
 756                 WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
 757 
 758                 /* setup UVD_MPC_SET_MUXA0 */
 759                 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXA0,
 760                         ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
 761                         (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
 762                         (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
 763                         (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
 764 
 765                 /* setup UVD_MPC_SET_MUXB0 */
 766                 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXB0,
 767                         ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
 768                         (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
 769                         (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
 770                         (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
 771 
 772                 /* setup mmUVD_MPC_SET_MUX */
 773                 WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUX,
 774                         ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
 775                         (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
 776                         (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
 777         }
 778 
 779         vcn_v2_5_mc_resume(adev);
 780 
 781         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 782                 if (adev->vcn.harvest_config & (1 << i))
 783                         continue;
 784                 /* VCN global tiling registers */
 785                 WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
 786                         adev->gfx.config.gb_addr_config);
 787                 WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
 788                         adev->gfx.config.gb_addr_config);
 789 
 790                 /* enable LMI MC and UMC channels */
 791                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0,
 792                         ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
 793 
 794                 /* unblock VCPU register access */
 795                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL), 0,
 796                         ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
 797 
 798                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
 799                         ~UVD_VCPU_CNTL__BLK_RST_MASK);
 800 
 801                 for (k = 0; k < 10; ++k) {
 802                         uint32_t status;
 803 
 804                         for (j = 0; j < 100; ++j) {
 805                                 status = RREG32_SOC15(UVD, i, mmUVD_STATUS);
 806                                 if (status & 2)
 807                                         break;
 808                                 if (amdgpu_emu_mode == 1)
 809                                         msleep(500);
 810                                 else
 811                                         mdelay(10);
 812                         }
 813                         r = 0;
 814                         if (status & 2)
 815                                 break;
 816 
 817                         DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
 818                         WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
 819                                 UVD_VCPU_CNTL__BLK_RST_MASK,
 820                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
 821                         mdelay(10);
 822                         WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
 823                                 ~UVD_VCPU_CNTL__BLK_RST_MASK);
 824 
 825                         mdelay(10);
 826                         r = -1;
 827                 }
 828 
 829                 if (r) {
 830                         DRM_ERROR("VCN decode not responding, giving up!!!\n");
 831                         return r;
 832                 }
 833 
 834                 /* enable master interrupt */
 835                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
 836                         UVD_MASTINT_EN__VCPU_EN_MASK,
 837                         ~UVD_MASTINT_EN__VCPU_EN_MASK);
 838 
 839                 /* clear the busy bit of VCN_STATUS */
 840                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0,
 841                         ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
 842 
 843                 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_VMID, 0);
 844 
 845                 ring = &adev->vcn.inst[i].ring_dec;
 846                 /* force RBC into idle state */
 847                 rb_bufsz = order_base_2(ring->ring_size);
 848                 tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
 849                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
 850                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
 851                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
 852                 tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
 853                 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, tmp);
 854 
 855                 /* programm the RB_BASE for ring buffer */
 856                 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
 857                         lower_32_bits(ring->gpu_addr));
 858                 WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
 859                         upper_32_bits(ring->gpu_addr));
 860 
 861                 /* Initialize the ring buffer's read and write pointers */
 862                 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR, 0);
 863 
 864                 ring->wptr = RREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR);
 865                 WREG32_SOC15(UVD, i, mmUVD_RBC_RB_WPTR,
 866                                 lower_32_bits(ring->wptr));
 867                 ring = &adev->vcn.inst[i].ring_enc[0];
 868                 WREG32_SOC15(UVD, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
 869                 WREG32_SOC15(UVD, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
 870                 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
 871                 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
 872                 WREG32_SOC15(UVD, i, mmUVD_RB_SIZE, ring->ring_size / 4);
 873 
 874                 ring = &adev->vcn.inst[i].ring_enc[1];
 875                 WREG32_SOC15(UVD, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
 876                 WREG32_SOC15(UVD, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
 877                 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
 878                 WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
 879                 WREG32_SOC15(UVD, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
 880         }
 881         r = jpeg_v2_5_start(adev);
 882 
 883         return r;
 884 }
 885 
 886 static int vcn_v2_5_stop(struct amdgpu_device *adev)
 887 {
 888         uint32_t tmp;
 889         int i, r;
 890 
 891         r = jpeg_v2_5_stop(adev);
 892         if (r)
 893                 return r;
 894 
 895         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 896                 if (adev->vcn.harvest_config & (1 << i))
 897                         continue;
 898                 /* wait for vcn idle */
 899                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
 900                 if (r)
 901                         return r;
 902 
 903                 tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
 904                         UVD_LMI_STATUS__READ_CLEAN_MASK |
 905                         UVD_LMI_STATUS__WRITE_CLEAN_MASK |
 906                         UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
 907                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
 908                 if (r)
 909                         return r;
 910 
 911                 /* block LMI UMC channel */
 912                 tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
 913                 tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
 914                 WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
 915 
 916                 tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
 917                         UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
 918                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
 919                 if (r)
 920                         return r;
 921 
 922                 /* block VCPU register access */
 923                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL),
 924                         UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
 925                         ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
 926 
 927                 /* reset VCPU */
 928                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
 929                         UVD_VCPU_CNTL__BLK_RST_MASK,
 930                         ~UVD_VCPU_CNTL__BLK_RST_MASK);
 931 
 932                 /* disable VCPU clock */
 933                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
 934                         ~(UVD_VCPU_CNTL__CLK_EN_MASK));
 935 
 936                 /* clear status */
 937                 WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
 938 
 939                 vcn_v2_5_enable_clock_gating(adev);
 940 
 941                 /* enable register anti-hang mechanism */
 942                 WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS),
 943                         UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
 944                         ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
 945         }
 946 
 947         return 0;
 948 }
 949 
 950 /**
 951  * vcn_v2_5_dec_ring_get_rptr - get read pointer
 952  *
 953  * @ring: amdgpu_ring pointer
 954  *
 955  * Returns the current hardware read pointer
 956  */
 957 static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
 958 {
 959         struct amdgpu_device *adev = ring->adev;
 960 
 961         return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR);
 962 }
 963 
 964 /**
 965  * vcn_v2_5_dec_ring_get_wptr - get write pointer
 966  *
 967  * @ring: amdgpu_ring pointer
 968  *
 969  * Returns the current hardware write pointer
 970  */
 971 static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
 972 {
 973         struct amdgpu_device *adev = ring->adev;
 974 
 975         if (ring->use_doorbell)
 976                 return adev->wb.wb[ring->wptr_offs];
 977         else
 978                 return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR);
 979 }
 980 
 981 /**
 982  * vcn_v2_5_dec_ring_set_wptr - set write pointer
 983  *
 984  * @ring: amdgpu_ring pointer
 985  *
 986  * Commits the write pointer to the hardware
 987  */
 988 static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
 989 {
 990         struct amdgpu_device *adev = ring->adev;
 991 
 992         if (ring->use_doorbell) {
 993                 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
 994                 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
 995         } else {
 996                 WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
 997         }
 998 }
 999 
1000 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
1001         .type = AMDGPU_RING_TYPE_VCN_DEC,
1002         .align_mask = 0xf,
1003         .vmhub = AMDGPU_MMHUB_1,
1004         .get_rptr = vcn_v2_5_dec_ring_get_rptr,
1005         .get_wptr = vcn_v2_5_dec_ring_get_wptr,
1006         .set_wptr = vcn_v2_5_dec_ring_set_wptr,
1007         .emit_frame_size =
1008                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1009                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1010                 8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1011                 14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1012                 6,
1013         .emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1014         .emit_ib = vcn_v2_0_dec_ring_emit_ib,
1015         .emit_fence = vcn_v2_0_dec_ring_emit_fence,
1016         .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1017         .test_ring = amdgpu_vcn_dec_ring_test_ring,
1018         .test_ib = amdgpu_vcn_dec_ring_test_ib,
1019         .insert_nop = vcn_v2_0_dec_ring_insert_nop,
1020         .insert_start = vcn_v2_0_dec_ring_insert_start,
1021         .insert_end = vcn_v2_0_dec_ring_insert_end,
1022         .pad_ib = amdgpu_ring_generic_pad_ib,
1023         .begin_use = amdgpu_vcn_ring_begin_use,
1024         .end_use = amdgpu_vcn_ring_end_use,
1025         .emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1026         .emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1027         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1028 };
1029 
1030 /**
1031  * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
1032  *
1033  * @ring: amdgpu_ring pointer
1034  *
1035  * Returns the current hardware enc read pointer
1036  */
1037 static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
1038 {
1039         struct amdgpu_device *adev = ring->adev;
1040 
1041         if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1042                 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR);
1043         else
1044                 return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2);
1045 }
1046 
1047 /**
1048  * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
1049  *
1050  * @ring: amdgpu_ring pointer
1051  *
1052  * Returns the current hardware enc write pointer
1053  */
1054 static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
1055 {
1056         struct amdgpu_device *adev = ring->adev;
1057 
1058         if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1059                 if (ring->use_doorbell)
1060                         return adev->wb.wb[ring->wptr_offs];
1061                 else
1062                         return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR);
1063         } else {
1064                 if (ring->use_doorbell)
1065                         return adev->wb.wb[ring->wptr_offs];
1066                 else
1067                         return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2);
1068         }
1069 }
1070 
1071 /**
1072  * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
1073  *
1074  * @ring: amdgpu_ring pointer
1075  *
1076  * Commits the enc write pointer to the hardware
1077  */
1078 static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
1079 {
1080         struct amdgpu_device *adev = ring->adev;
1081 
1082         if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1083                 if (ring->use_doorbell) {
1084                         adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1085                         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1086                 } else {
1087                         WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1088                 }
1089         } else {
1090                 if (ring->use_doorbell) {
1091                         adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1092                         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1093                 } else {
1094                         WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1095                 }
1096         }
1097 }
1098 
1099 static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
1100         .type = AMDGPU_RING_TYPE_VCN_ENC,
1101         .align_mask = 0x3f,
1102         .nop = VCN_ENC_CMD_NO_OP,
1103         .vmhub = AMDGPU_MMHUB_1,
1104         .get_rptr = vcn_v2_5_enc_ring_get_rptr,
1105         .get_wptr = vcn_v2_5_enc_ring_get_wptr,
1106         .set_wptr = vcn_v2_5_enc_ring_set_wptr,
1107         .emit_frame_size =
1108                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1109                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1110                 4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1111                 5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1112                 1, /* vcn_v2_0_enc_ring_insert_end */
1113         .emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1114         .emit_ib = vcn_v2_0_enc_ring_emit_ib,
1115         .emit_fence = vcn_v2_0_enc_ring_emit_fence,
1116         .emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1117         .test_ring = amdgpu_vcn_enc_ring_test_ring,
1118         .test_ib = amdgpu_vcn_enc_ring_test_ib,
1119         .insert_nop = amdgpu_ring_insert_nop,
1120         .insert_end = vcn_v2_0_enc_ring_insert_end,
1121         .pad_ib = amdgpu_ring_generic_pad_ib,
1122         .begin_use = amdgpu_vcn_ring_begin_use,
1123         .end_use = amdgpu_vcn_ring_end_use,
1124         .emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1125         .emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1126         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1127 };
1128 
1129 /**
1130  * vcn_v2_5_jpeg_ring_get_rptr - get read pointer
1131  *
1132  * @ring: amdgpu_ring pointer
1133  *
1134  * Returns the current hardware read pointer
1135  */
1136 static uint64_t vcn_v2_5_jpeg_ring_get_rptr(struct amdgpu_ring *ring)
1137 {
1138         struct amdgpu_device *adev = ring->adev;
1139 
1140         return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_RPTR);
1141 }
1142 
1143 /**
1144  * vcn_v2_5_jpeg_ring_get_wptr - get write pointer
1145  *
1146  * @ring: amdgpu_ring pointer
1147  *
1148  * Returns the current hardware write pointer
1149  */
1150 static uint64_t vcn_v2_5_jpeg_ring_get_wptr(struct amdgpu_ring *ring)
1151 {
1152         struct amdgpu_device *adev = ring->adev;
1153 
1154         if (ring->use_doorbell)
1155                 return adev->wb.wb[ring->wptr_offs];
1156         else
1157                 return RREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR);
1158 }
1159 
1160 /**
1161  * vcn_v2_5_jpeg_ring_set_wptr - set write pointer
1162  *
1163  * @ring: amdgpu_ring pointer
1164  *
1165  * Commits the write pointer to the hardware
1166  */
1167 static void vcn_v2_5_jpeg_ring_set_wptr(struct amdgpu_ring *ring)
1168 {
1169         struct amdgpu_device *adev = ring->adev;
1170 
1171         if (ring->use_doorbell) {
1172                 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
1173                 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1174         } else {
1175                 WREG32_SOC15(UVD, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
1176         }
1177 }
1178 
1179 static const struct amdgpu_ring_funcs vcn_v2_5_jpeg_ring_vm_funcs = {
1180         .type = AMDGPU_RING_TYPE_VCN_JPEG,
1181         .align_mask = 0xf,
1182         .vmhub = AMDGPU_MMHUB_1,
1183         .get_rptr = vcn_v2_5_jpeg_ring_get_rptr,
1184         .get_wptr = vcn_v2_5_jpeg_ring_get_wptr,
1185         .set_wptr = vcn_v2_5_jpeg_ring_set_wptr,
1186         .emit_frame_size =
1187                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1188                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1189                 8 + /* vcn_v2_0_jpeg_ring_emit_vm_flush */
1190                 18 + 18 + /* vcn_v2_0_jpeg_ring_emit_fence x2 vm fence */
1191                 8 + 16,
1192         .emit_ib_size = 22, /* vcn_v2_0_jpeg_ring_emit_ib */
1193         .emit_ib = vcn_v2_0_jpeg_ring_emit_ib,
1194         .emit_fence = vcn_v2_0_jpeg_ring_emit_fence,
1195         .emit_vm_flush = vcn_v2_0_jpeg_ring_emit_vm_flush,
1196         .test_ring = amdgpu_vcn_jpeg_ring_test_ring,
1197         .test_ib = amdgpu_vcn_jpeg_ring_test_ib,
1198         .insert_nop = vcn_v2_0_jpeg_ring_nop,
1199         .insert_start = vcn_v2_0_jpeg_ring_insert_start,
1200         .insert_end = vcn_v2_0_jpeg_ring_insert_end,
1201         .pad_ib = amdgpu_ring_generic_pad_ib,
1202         .begin_use = amdgpu_vcn_ring_begin_use,
1203         .end_use = amdgpu_vcn_ring_end_use,
1204         .emit_wreg = vcn_v2_0_jpeg_ring_emit_wreg,
1205         .emit_reg_wait = vcn_v2_0_jpeg_ring_emit_reg_wait,
1206         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1207 };
1208 
1209 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
1210 {
1211         int i;
1212 
1213         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1214                 if (adev->vcn.harvest_config & (1 << i))
1215                         continue;
1216                 adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
1217                 adev->vcn.inst[i].ring_dec.me = i;
1218                 DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
1219         }
1220 }
1221 
1222 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1223 {
1224         int i, j;
1225 
1226         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1227                 if (adev->vcn.harvest_config & (1 << j))
1228                         continue;
1229                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
1230                         adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1231                         adev->vcn.inst[j].ring_enc[i].me = j;
1232                 }
1233                 DRM_INFO("VCN(%d) encode is enabled in VM mode\n", j);
1234         }
1235 }
1236 
1237 static void vcn_v2_5_set_jpeg_ring_funcs(struct amdgpu_device *adev)
1238 {
1239         int i;
1240 
1241         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1242                 if (adev->vcn.harvest_config & (1 << i))
1243                         continue;
1244                 adev->vcn.inst[i].ring_jpeg.funcs = &vcn_v2_5_jpeg_ring_vm_funcs;
1245                 adev->vcn.inst[i].ring_jpeg.me = i;
1246                 DRM_INFO("VCN(%d) jpeg decode is enabled in VM mode\n", i);
1247         }
1248 }
1249 
1250 static bool vcn_v2_5_is_idle(void *handle)
1251 {
1252         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1253         int i, ret = 1;
1254 
1255         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1256                 if (adev->vcn.harvest_config & (1 << i))
1257                         continue;
1258                 ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1259         }
1260 
1261         return ret;
1262 }
1263 
1264 static int vcn_v2_5_wait_for_idle(void *handle)
1265 {
1266         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1267         int i, ret = 0;
1268 
1269         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1270                 if (adev->vcn.harvest_config & (1 << i))
1271                         continue;
1272                 SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1273                         UVD_STATUS__IDLE, ret);
1274                 if (ret)
1275                         return ret;
1276         }
1277 
1278         return ret;
1279 }
1280 
1281 static int vcn_v2_5_set_clockgating_state(void *handle,
1282                                           enum amd_clockgating_state state)
1283 {
1284         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1285         bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1286 
1287         if (enable) {
1288                 if (vcn_v2_5_is_idle(handle))
1289                         return -EBUSY;
1290                 vcn_v2_5_enable_clock_gating(adev);
1291         } else {
1292                 vcn_v2_5_disable_clock_gating(adev);
1293         }
1294 
1295         return 0;
1296 }
1297 
1298 static int vcn_v2_5_set_powergating_state(void *handle,
1299                                           enum amd_powergating_state state)
1300 {
1301         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1302         int ret;
1303 
1304         if(state == adev->vcn.cur_state)
1305                 return 0;
1306 
1307         if (state == AMD_PG_STATE_GATE)
1308                 ret = vcn_v2_5_stop(adev);
1309         else
1310                 ret = vcn_v2_5_start(adev);
1311 
1312         if(!ret)
1313                 adev->vcn.cur_state = state;
1314 
1315         return ret;
1316 }
1317 
1318 static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
1319                                         struct amdgpu_irq_src *source,
1320                                         unsigned type,
1321                                         enum amdgpu_interrupt_state state)
1322 {
1323         return 0;
1324 }
1325 
1326 static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
1327                                       struct amdgpu_irq_src *source,
1328                                       struct amdgpu_iv_entry *entry)
1329 {
1330         uint32_t ip_instance;
1331 
1332         switch (entry->client_id) {
1333         case SOC15_IH_CLIENTID_VCN:
1334                 ip_instance = 0;
1335                 break;
1336         case SOC15_IH_CLIENTID_VCN1:
1337                 ip_instance = 1;
1338                 break;
1339         default:
1340                 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1341                 return 0;
1342         }
1343 
1344         DRM_DEBUG("IH: VCN TRAP\n");
1345 
1346         switch (entry->src_id) {
1347         case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1348                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
1349                 break;
1350         case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1351                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1352                 break;
1353         case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1354                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
1355                 break;
1356         case VCN_2_0__SRCID__JPEG_DECODE:
1357                 amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_jpeg);
1358                 break;
1359         default:
1360                 DRM_ERROR("Unhandled interrupt: %d %d\n",
1361                           entry->src_id, entry->src_data[0]);
1362                 break;
1363         }
1364 
1365         return 0;
1366 }
1367 
1368 static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
1369         .set = vcn_v2_5_set_interrupt_state,
1370         .process = vcn_v2_5_process_interrupt,
1371 };
1372 
1373 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
1374 {
1375         int i;
1376 
1377         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1378                 if (adev->vcn.harvest_config & (1 << i))
1379                         continue;
1380                 adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 2;
1381                 adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
1382         }
1383 }
1384 
1385 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
1386         .name = "vcn_v2_5",
1387         .early_init = vcn_v2_5_early_init,
1388         .late_init = NULL,
1389         .sw_init = vcn_v2_5_sw_init,
1390         .sw_fini = vcn_v2_5_sw_fini,
1391         .hw_init = vcn_v2_5_hw_init,
1392         .hw_fini = vcn_v2_5_hw_fini,
1393         .suspend = vcn_v2_5_suspend,
1394         .resume = vcn_v2_5_resume,
1395         .is_idle = vcn_v2_5_is_idle,
1396         .wait_for_idle = vcn_v2_5_wait_for_idle,
1397         .check_soft_reset = NULL,
1398         .pre_soft_reset = NULL,
1399         .soft_reset = NULL,
1400         .post_soft_reset = NULL,
1401         .set_clockgating_state = vcn_v2_5_set_clockgating_state,
1402         .set_powergating_state = vcn_v2_5_set_powergating_state,
1403 };
1404 
1405 const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
1406 {
1407                 .type = AMD_IP_BLOCK_TYPE_VCN,
1408                 .major = 2,
1409                 .minor = 5,
1410                 .rev = 0,
1411                 .funcs = &vcn_v2_5_ip_funcs,
1412 };

/* [<][>][^][v][top][bottom][index][help] */