linux/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.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 "amdgpu.h"
  25#include "amdgpu_jpeg.h"
  26#include "soc15.h"
  27#include "soc15d.h"
  28#include "vcn_v1_0.h"
  29#include "jpeg_v1_0.h"
  30
  31#include "vcn/vcn_1_0_offset.h"
  32#include "vcn/vcn_1_0_sh_mask.h"
  33
  34static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
  35static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
  36static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
  37
  38static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
  39{
  40        struct amdgpu_device *adev = ring->adev;
  41        ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
  42        if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
  43                ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
  44                ring->ring[(*ptr)++] = 0;
  45                ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0);
  46        } else {
  47                ring->ring[(*ptr)++] = reg_offset;
  48                ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0);
  49        }
  50        ring->ring[(*ptr)++] = val;
  51}
  52
  53static void jpeg_v1_0_decode_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr)
  54{
  55        struct amdgpu_device *adev = ring->adev;
  56
  57        uint32_t reg, reg_offset, val, mask, i;
  58
  59        // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW
  60        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW);
  61        reg_offset = (reg << 2);
  62        val = lower_32_bits(ring->gpu_addr);
  63        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
  64
  65        // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH
  66        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH);
  67        reg_offset = (reg << 2);
  68        val = upper_32_bits(ring->gpu_addr);
  69        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
  70
  71        // 3rd to 5th: issue MEM_READ commands
  72        for (i = 0; i <= 2; i++) {
  73                ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2);
  74                ring->ring[ptr++] = 0;
  75        }
  76
  77        // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability
  78        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
  79        reg_offset = (reg << 2);
  80        val = 0x13;
  81        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
  82
  83        // 7th: program mmUVD_JRBC_RB_REF_DATA
  84        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA);
  85        reg_offset = (reg << 2);
  86        val = 0x1;
  87        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
  88
  89        // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL
  90        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
  91        reg_offset = (reg << 2);
  92        val = 0x1;
  93        mask = 0x1;
  94
  95        ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0);
  96        ring->ring[ptr++] = 0x01400200;
  97        ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0);
  98        ring->ring[ptr++] = val;
  99        ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
 100        if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
 101                ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
 102                ring->ring[ptr++] = 0;
 103                ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3);
 104        } else {
 105                ring->ring[ptr++] = reg_offset;
 106                ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3);
 107        }
 108        ring->ring[ptr++] = mask;
 109
 110        //9th to 21st: insert no-op
 111        for (i = 0; i <= 12; i++) {
 112                ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
 113                ring->ring[ptr++] = 0;
 114        }
 115
 116        //22nd: reset mmUVD_JRBC_RB_RPTR
 117        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_RPTR);
 118        reg_offset = (reg << 2);
 119        val = 0;
 120        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
 121
 122        //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch
 123        reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
 124        reg_offset = (reg << 2);
 125        val = 0x12;
 126        jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
 127}
 128
 129/**
 130 * jpeg_v1_0_decode_ring_get_rptr - get read pointer
 131 *
 132 * @ring: amdgpu_ring pointer
 133 *
 134 * Returns the current hardware read pointer
 135 */
 136static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring)
 137{
 138        struct amdgpu_device *adev = ring->adev;
 139
 140        return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
 141}
 142
 143/**
 144 * jpeg_v1_0_decode_ring_get_wptr - get write pointer
 145 *
 146 * @ring: amdgpu_ring pointer
 147 *
 148 * Returns the current hardware write pointer
 149 */
 150static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring)
 151{
 152        struct amdgpu_device *adev = ring->adev;
 153
 154        return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
 155}
 156
 157/**
 158 * jpeg_v1_0_decode_ring_set_wptr - set write pointer
 159 *
 160 * @ring: amdgpu_ring pointer
 161 *
 162 * Commits the write pointer to the hardware
 163 */
 164static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring)
 165{
 166        struct amdgpu_device *adev = ring->adev;
 167
 168        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
 169}
 170
 171/**
 172 * jpeg_v1_0_decode_ring_insert_start - insert a start command
 173 *
 174 * @ring: amdgpu_ring pointer
 175 *
 176 * Write a start command to the ring.
 177 */
 178static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring)
 179{
 180        struct amdgpu_device *adev = ring->adev;
 181
 182        amdgpu_ring_write(ring,
 183                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
 184        amdgpu_ring_write(ring, 0x68e04);
 185
 186        amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
 187        amdgpu_ring_write(ring, 0x80010000);
 188}
 189
 190/**
 191 * jpeg_v1_0_decode_ring_insert_end - insert a end command
 192 *
 193 * @ring: amdgpu_ring pointer
 194 *
 195 * Write a end command to the ring.
 196 */
 197static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring)
 198{
 199        struct amdgpu_device *adev = ring->adev;
 200
 201        amdgpu_ring_write(ring,
 202                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
 203        amdgpu_ring_write(ring, 0x68e04);
 204
 205        amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
 206        amdgpu_ring_write(ring, 0x00010000);
 207}
 208
 209/**
 210 * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command
 211 *
 212 * @ring: amdgpu_ring pointer
 213 * @addr: address
 214 * @seq: sequence number
 215 * @flags: fence related flags
 216 *
 217 * Write a fence and a trap command to the ring.
 218 */
 219static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
 220                                     unsigned flags)
 221{
 222        struct amdgpu_device *adev = ring->adev;
 223
 224        WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
 225
 226        amdgpu_ring_write(ring,
 227                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0));
 228        amdgpu_ring_write(ring, seq);
 229
 230        amdgpu_ring_write(ring,
 231                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0));
 232        amdgpu_ring_write(ring, seq);
 233
 234        amdgpu_ring_write(ring,
 235                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
 236        amdgpu_ring_write(ring, lower_32_bits(addr));
 237
 238        amdgpu_ring_write(ring,
 239                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
 240        amdgpu_ring_write(ring, upper_32_bits(addr));
 241
 242        amdgpu_ring_write(ring,
 243                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0));
 244        amdgpu_ring_write(ring, 0x8);
 245
 246        amdgpu_ring_write(ring,
 247                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
 248        amdgpu_ring_write(ring, 0);
 249
 250        amdgpu_ring_write(ring,
 251                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
 252        amdgpu_ring_write(ring, 0x01400200);
 253
 254        amdgpu_ring_write(ring,
 255                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
 256        amdgpu_ring_write(ring, seq);
 257
 258        amdgpu_ring_write(ring,
 259                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
 260        amdgpu_ring_write(ring, lower_32_bits(addr));
 261
 262        amdgpu_ring_write(ring,
 263                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
 264        amdgpu_ring_write(ring, upper_32_bits(addr));
 265
 266        amdgpu_ring_write(ring,
 267                PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2));
 268        amdgpu_ring_write(ring, 0xffffffff);
 269
 270        amdgpu_ring_write(ring,
 271                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
 272        amdgpu_ring_write(ring, 0x3fbc);
 273
 274        amdgpu_ring_write(ring,
 275                PACKETJ(0, 0, 0, PACKETJ_TYPE0));
 276        amdgpu_ring_write(ring, 0x1);
 277
 278        /* emit trap */
 279        amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
 280        amdgpu_ring_write(ring, 0);
 281}
 282
 283/**
 284 * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer
 285 *
 286 * @ring: amdgpu_ring pointer
 287 * @job: job to retrieve vmid from
 288 * @ib: indirect buffer to execute
 289 * @flags: unused
 290 *
 291 * Write ring commands to execute the indirect buffer.
 292 */
 293static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring,
 294                                        struct amdgpu_job *job,
 295                                        struct amdgpu_ib *ib,
 296                                        uint32_t flags)
 297{
 298        struct amdgpu_device *adev = ring->adev;
 299        unsigned vmid = AMDGPU_JOB_GET_VMID(job);
 300
 301        amdgpu_ring_write(ring,
 302                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0));
 303        amdgpu_ring_write(ring, (vmid | (vmid << 4)));
 304
 305        amdgpu_ring_write(ring,
 306                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0));
 307        amdgpu_ring_write(ring, (vmid | (vmid << 4)));
 308
 309        amdgpu_ring_write(ring,
 310                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
 311        amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
 312
 313        amdgpu_ring_write(ring,
 314                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
 315        amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
 316
 317        amdgpu_ring_write(ring,
 318                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0));
 319        amdgpu_ring_write(ring, ib->length_dw);
 320
 321        amdgpu_ring_write(ring,
 322                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
 323        amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
 324
 325        amdgpu_ring_write(ring,
 326                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
 327        amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
 328
 329        amdgpu_ring_write(ring,
 330                PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
 331        amdgpu_ring_write(ring, 0);
 332
 333        amdgpu_ring_write(ring,
 334                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
 335        amdgpu_ring_write(ring, 0x01400200);
 336
 337        amdgpu_ring_write(ring,
 338                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
 339        amdgpu_ring_write(ring, 0x2);
 340
 341        amdgpu_ring_write(ring,
 342                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
 343        amdgpu_ring_write(ring, 0x2);
 344}
 345
 346static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring,
 347                                            uint32_t reg, uint32_t val,
 348                                            uint32_t mask)
 349{
 350        struct amdgpu_device *adev = ring->adev;
 351        uint32_t reg_offset = (reg << 2);
 352
 353        amdgpu_ring_write(ring,
 354                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
 355        amdgpu_ring_write(ring, 0x01400200);
 356
 357        amdgpu_ring_write(ring,
 358                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
 359        amdgpu_ring_write(ring, val);
 360
 361        amdgpu_ring_write(ring,
 362                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
 363        if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
 364                ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
 365                amdgpu_ring_write(ring, 0);
 366                amdgpu_ring_write(ring,
 367                        PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
 368        } else {
 369                amdgpu_ring_write(ring, reg_offset);
 370                amdgpu_ring_write(ring,
 371                        PACKETJ(0, 0, 0, PACKETJ_TYPE3));
 372        }
 373        amdgpu_ring_write(ring, mask);
 374}
 375
 376static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring,
 377                unsigned vmid, uint64_t pd_addr)
 378{
 379        struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
 380        uint32_t data0, data1, mask;
 381
 382        pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
 383
 384        /* wait for register write */
 385        data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;
 386        data1 = lower_32_bits(pd_addr);
 387        mask = 0xffffffff;
 388        jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask);
 389}
 390
 391static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring,
 392                                        uint32_t reg, uint32_t val)
 393{
 394        struct amdgpu_device *adev = ring->adev;
 395        uint32_t reg_offset = (reg << 2);
 396
 397        amdgpu_ring_write(ring,
 398                PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
 399        if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
 400                        ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
 401                amdgpu_ring_write(ring, 0);
 402                amdgpu_ring_write(ring,
 403                        PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
 404        } else {
 405                amdgpu_ring_write(ring, reg_offset);
 406                amdgpu_ring_write(ring,
 407                        PACKETJ(0, 0, 0, PACKETJ_TYPE0));
 408        }
 409        amdgpu_ring_write(ring, val);
 410}
 411
 412static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count)
 413{
 414        int i;
 415
 416        WARN_ON(ring->wptr % 2 || count % 2);
 417
 418        for (i = 0; i < count / 2; i++) {
 419                amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
 420                amdgpu_ring_write(ring, 0);
 421        }
 422}
 423
 424static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev,
 425                                        struct amdgpu_irq_src *source,
 426                                        unsigned type,
 427                                        enum amdgpu_interrupt_state state)
 428{
 429        return 0;
 430}
 431
 432static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,
 433                                      struct amdgpu_irq_src *source,
 434                                      struct amdgpu_iv_entry *entry)
 435{
 436        DRM_DEBUG("IH: JPEG decode TRAP\n");
 437
 438        switch (entry->src_id) {
 439        case 126:
 440                amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
 441                break;
 442        default:
 443                DRM_ERROR("Unhandled interrupt: %d %d\n",
 444                          entry->src_id, entry->src_data[0]);
 445                break;
 446        }
 447
 448        return 0;
 449}
 450
 451/**
 452 * jpeg_v1_0_early_init - set function pointers
 453 *
 454 * @handle: amdgpu_device pointer
 455 *
 456 * Set ring and irq function pointers
 457 */
 458int jpeg_v1_0_early_init(void *handle)
 459{
 460        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 461
 462        adev->jpeg.num_jpeg_inst = 1;
 463
 464        jpeg_v1_0_set_dec_ring_funcs(adev);
 465        jpeg_v1_0_set_irq_funcs(adev);
 466
 467        return 0;
 468}
 469
 470/**
 471 * jpeg_v1_0_sw_init - sw init for JPEG block
 472 *
 473 * @handle: amdgpu_device pointer
 474 *
 475 */
 476int jpeg_v1_0_sw_init(void *handle)
 477{
 478        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 479        struct amdgpu_ring *ring;
 480        int r;
 481
 482        /* JPEG TRAP */
 483        r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq);
 484        if (r)
 485                return r;
 486
 487        ring = &adev->jpeg.inst->ring_dec;
 488        sprintf(ring->name, "jpeg_dec");
 489        r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
 490                             0, AMDGPU_RING_PRIO_DEFAULT, NULL);
 491        if (r)
 492                return r;
 493
 494        adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch =
 495                SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
 496
 497        return 0;
 498}
 499
 500/**
 501 * jpeg_v1_0_sw_fini - sw fini for JPEG block
 502 *
 503 * @handle: amdgpu_device pointer
 504 *
 505 * JPEG free up sw allocation
 506 */
 507void jpeg_v1_0_sw_fini(void *handle)
 508{
 509        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 510
 511        amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec);
 512}
 513
 514/**
 515 * jpeg_v1_0_start - start JPEG block
 516 *
 517 * @adev: amdgpu_device pointer
 518 * @mode: SPG or DPG mode
 519 *
 520 * Setup and start the JPEG block
 521 */
 522void jpeg_v1_0_start(struct amdgpu_device *adev, int mode)
 523{
 524        struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
 525
 526        if (mode == 0) {
 527                WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
 528                WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
 529                                UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
 530                WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr));
 531                WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr));
 532                WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
 533                WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
 534                WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
 535        }
 536
 537        /* initialize wptr */
 538        ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
 539
 540        /* copy patch commands to the jpeg ring */
 541        jpeg_v1_0_decode_ring_set_patch_ring(ring,
 542                (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission));
 543}
 544
 545static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {
 546        .type = AMDGPU_RING_TYPE_VCN_JPEG,
 547        .align_mask = 0xf,
 548        .nop = PACKET0(0x81ff, 0),
 549        .support_64bit_ptrs = false,
 550        .no_user_fence = true,
 551        .vmhub = AMDGPU_MMHUB_0,
 552        .extra_dw = 64,
 553        .get_rptr = jpeg_v1_0_decode_ring_get_rptr,
 554        .get_wptr = jpeg_v1_0_decode_ring_get_wptr,
 555        .set_wptr = jpeg_v1_0_decode_ring_set_wptr,
 556        .emit_frame_size =
 557                6 + 6 + /* hdp invalidate / flush */
 558                SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 559                SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
 560                8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */
 561                26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */
 562                6,
 563        .emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */
 564        .emit_ib = jpeg_v1_0_decode_ring_emit_ib,
 565        .emit_fence = jpeg_v1_0_decode_ring_emit_fence,
 566        .emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush,
 567        .test_ring = amdgpu_jpeg_dec_ring_test_ring,
 568        .test_ib = amdgpu_jpeg_dec_ring_test_ib,
 569        .insert_nop = jpeg_v1_0_decode_ring_nop,
 570        .insert_start = jpeg_v1_0_decode_ring_insert_start,
 571        .insert_end = jpeg_v1_0_decode_ring_insert_end,
 572        .pad_ib = amdgpu_ring_generic_pad_ib,
 573        .begin_use = jpeg_v1_0_ring_begin_use,
 574        .end_use = vcn_v1_0_ring_end_use,
 575        .emit_wreg = jpeg_v1_0_decode_ring_emit_wreg,
 576        .emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait,
 577        .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
 578};
 579
 580static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
 581{
 582        adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs;
 583        DRM_INFO("JPEG decode is enabled in VM mode\n");
 584}
 585
 586static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = {
 587        .set = jpeg_v1_0_set_interrupt_state,
 588        .process = jpeg_v1_0_process_interrupt,
 589};
 590
 591static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev)
 592{
 593        adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs;
 594}
 595
 596static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
 597{
 598        struct  amdgpu_device *adev = ring->adev;
 599        bool    set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
 600        int             cnt = 0;
 601
 602        mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
 603
 604        if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_dec))
 605                DRM_ERROR("JPEG dec: vcn dec ring may not be empty\n");
 606
 607        for (cnt = 0; cnt < adev->vcn.num_enc_rings; cnt++) {
 608                if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_enc[cnt]))
 609                        DRM_ERROR("JPEG dec: vcn enc ring[%d] may not be empty\n", cnt);
 610        }
 611
 612        vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
 613}
 614