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