linux/drivers/gpu/drm/amd/amdgpu/jpeg_v2_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 "amdgpu_pm.h"
  27#include "soc15.h"
  28#include "soc15d.h"
  29#include "jpeg_v2_0.h"
  30
  31#include "vcn/vcn_2_0_0_offset.h"
  32#include "vcn/vcn_2_0_0_sh_mask.h"
  33#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
  34
  35#define mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET                         0x1bfff
  36#define mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET                            0x4029
  37#define mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET                          0x402a
  38#define mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET                          0x402b
  39#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET          0x40ea
  40#define mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET         0x40eb
  41#define mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET                          0x40cf
  42#define mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET                             0x40d1
  43#define mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET                 0x40e8
  44#define mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET                0x40e9
  45#define mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET                              0x4082
  46#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET          0x40ec
  47#define mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET         0x40ed
  48#define mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET                     0x4085
  49#define mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET                          0x4084
  50#define mmUVD_JRBC_STATUS_INTERNAL_OFFSET                               0x4089
  51#define mmUVD_JPEG_PITCH_INTERNAL_OFFSET                                0x401f
  52
  53#define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR                                0x18000
  54
  55static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev);
  56static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev);
  57static int jpeg_v2_0_set_powergating_state(void *handle,
  58                                enum amd_powergating_state state);
  59
  60/**
  61 * jpeg_v2_0_early_init - set function pointers
  62 *
  63 * @handle: amdgpu_device pointer
  64 *
  65 * Set ring and irq function pointers
  66 */
  67static int jpeg_v2_0_early_init(void *handle)
  68{
  69        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  70
  71        adev->jpeg.num_jpeg_inst = 1;
  72
  73        jpeg_v2_0_set_dec_ring_funcs(adev);
  74        jpeg_v2_0_set_irq_funcs(adev);
  75
  76        return 0;
  77}
  78
  79/**
  80 * jpeg_v2_0_sw_init - sw init for JPEG block
  81 *
  82 * @handle: amdgpu_device pointer
  83 *
  84 * Load firmware and sw initialization
  85 */
  86static int jpeg_v2_0_sw_init(void *handle)
  87{
  88        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  89        struct amdgpu_ring *ring;
  90        int r;
  91
  92        /* JPEG TRAP */
  93        r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
  94                VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
  95        if (r)
  96                return r;
  97
  98        r = amdgpu_jpeg_sw_init(adev);
  99        if (r)
 100                return r;
 101
 102        r = amdgpu_jpeg_resume(adev);
 103        if (r)
 104                return r;
 105
 106        ring = &adev->jpeg.inst->ring_dec;
 107        ring->use_doorbell = true;
 108        ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
 109        sprintf(ring->name, "jpeg_dec");
 110        r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
 111                             0, AMDGPU_RING_PRIO_DEFAULT, NULL);
 112        if (r)
 113                return r;
 114
 115        adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
 116        adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
 117
 118        return 0;
 119}
 120
 121/**
 122 * jpeg_v2_0_sw_fini - sw fini for JPEG block
 123 *
 124 * @handle: amdgpu_device pointer
 125 *
 126 * JPEG suspend and free up sw allocation
 127 */
 128static int jpeg_v2_0_sw_fini(void *handle)
 129{
 130        int r;
 131        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 132
 133        r = amdgpu_jpeg_suspend(adev);
 134        if (r)
 135                return r;
 136
 137        r = amdgpu_jpeg_sw_fini(adev);
 138
 139        return r;
 140}
 141
 142/**
 143 * jpeg_v2_0_hw_init - start and test JPEG block
 144 *
 145 * @handle: amdgpu_device pointer
 146 *
 147 */
 148static int jpeg_v2_0_hw_init(void *handle)
 149{
 150        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 151        struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
 152        int r;
 153
 154        adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
 155                (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
 156
 157        r = amdgpu_ring_test_helper(ring);
 158        if (!r)
 159                DRM_INFO("JPEG decode initialized successfully.\n");
 160
 161        return r;
 162}
 163
 164/**
 165 * jpeg_v2_0_hw_fini - stop the hardware block
 166 *
 167 * @handle: amdgpu_device pointer
 168 *
 169 * Stop the JPEG block, mark ring as not ready any more
 170 */
 171static int jpeg_v2_0_hw_fini(void *handle)
 172{
 173        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 174
 175        cancel_delayed_work_sync(&adev->vcn.idle_work);
 176
 177        if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
 178              RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
 179                jpeg_v2_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 180
 181        return 0;
 182}
 183
 184/**
 185 * jpeg_v2_0_suspend - suspend JPEG block
 186 *
 187 * @handle: amdgpu_device pointer
 188 *
 189 * HW fini and suspend JPEG block
 190 */
 191static int jpeg_v2_0_suspend(void *handle)
 192{
 193        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 194        int r;
 195
 196        r = jpeg_v2_0_hw_fini(adev);
 197        if (r)
 198                return r;
 199
 200        r = amdgpu_jpeg_suspend(adev);
 201
 202        return r;
 203}
 204
 205/**
 206 * jpeg_v2_0_resume - resume JPEG block
 207 *
 208 * @handle: amdgpu_device pointer
 209 *
 210 * Resume firmware and hw init JPEG block
 211 */
 212static int jpeg_v2_0_resume(void *handle)
 213{
 214        int r;
 215        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 216
 217        r = amdgpu_jpeg_resume(adev);
 218        if (r)
 219                return r;
 220
 221        r = jpeg_v2_0_hw_init(adev);
 222
 223        return r;
 224}
 225
 226static int jpeg_v2_0_disable_power_gating(struct amdgpu_device *adev)
 227{
 228        uint32_t data;
 229        int r = 0;
 230
 231        if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
 232                data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
 233                WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
 234
 235                r = SOC15_WAIT_ON_RREG(JPEG, 0,
 236                        mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
 237                        UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
 238
 239                if (r) {
 240                        DRM_ERROR("amdgpu: JPEG disable power gating failed\n");
 241                        return r;
 242                }
 243        }
 244
 245        /* Removing the anti hang mechanism to indicate the UVDJ tile is ON */
 246        data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS)) & ~0x1;
 247        WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data);
 248
 249        return 0;
 250}
 251
 252static int jpeg_v2_0_enable_power_gating(struct amdgpu_device *adev)
 253{
 254        if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
 255                uint32_t data;
 256                int r = 0;
 257
 258                data = RREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS));
 259                data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
 260                data |=  0x1; //UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_TILES_OFF;
 261                WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), data);
 262
 263                data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
 264                WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
 265
 266                r = SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_PGFSM_STATUS,
 267                        (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
 268                        UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
 269
 270                if (r) {
 271                        DRM_ERROR("amdgpu: JPEG enable power gating failed\n");
 272                        return r;
 273                }
 274        }
 275
 276        return 0;
 277}
 278
 279static void jpeg_v2_0_disable_clock_gating(struct amdgpu_device *adev)
 280{
 281        uint32_t data;
 282
 283        data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
 284        if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
 285                data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 286        else
 287                data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 288
 289        data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
 290        data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
 291        WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
 292
 293        data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
 294        data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
 295                | JPEG_CGC_GATE__JPEG2_DEC_MASK
 296                | JPEG_CGC_GATE__JPEG_ENC_MASK
 297                | JPEG_CGC_GATE__JMCIF_MASK
 298                | JPEG_CGC_GATE__JRBBM_MASK);
 299        WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
 300}
 301
 302static void jpeg_v2_0_enable_clock_gating(struct amdgpu_device *adev)
 303{
 304        uint32_t data;
 305
 306        data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
 307        if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
 308                data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 309        else
 310                data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
 311
 312        data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
 313        data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
 314        WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
 315
 316        data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
 317        data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
 318                |JPEG_CGC_GATE__JPEG2_DEC_MASK
 319                |JPEG_CGC_GATE__JPEG_ENC_MASK
 320                |JPEG_CGC_GATE__JMCIF_MASK
 321                |JPEG_CGC_GATE__JRBBM_MASK);
 322        WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
 323}
 324
 325/**
 326 * jpeg_v2_0_start - start JPEG block
 327 *
 328 * @adev: amdgpu_device pointer
 329 *
 330 * Setup and start the JPEG block
 331 */
 332static int jpeg_v2_0_start(struct amdgpu_device *adev)
 333{
 334        struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
 335        int r;
 336
 337        if (adev->pm.dpm_enabled)
 338                amdgpu_dpm_enable_jpeg(adev, true);
 339
 340        /* disable power gating */
 341        r = jpeg_v2_0_disable_power_gating(adev);
 342        if (r)
 343                return r;
 344
 345        /* JPEG disable CGC */
 346        jpeg_v2_0_disable_clock_gating(adev);
 347
 348        WREG32_SOC15(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG, adev->gfx.config.gb_addr_config);
 349
 350        /* enable JMI channel */
 351        WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 0,
 352                ~UVD_JMI_CNTL__SOFT_RESET_MASK);
 353
 354        /* enable System Interrupt for JRBC */
 355        WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmJPEG_SYS_INT_EN),
 356                JPEG_SYS_INT_EN__DJRBC_MASK,
 357                ~JPEG_SYS_INT_EN__DJRBC_MASK);
 358
 359        WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
 360        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
 361        WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
 362                lower_32_bits(ring->gpu_addr));
 363        WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
 364                upper_32_bits(ring->gpu_addr));
 365        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
 366        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
 367        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L);
 368        WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
 369        ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
 370
 371        return 0;
 372}
 373
 374/**
 375 * jpeg_v2_0_stop - stop JPEG block
 376 *
 377 * @adev: amdgpu_device pointer
 378 *
 379 * stop the JPEG block
 380 */
 381static int jpeg_v2_0_stop(struct amdgpu_device *adev)
 382{
 383        int r;
 384
 385        /* reset JMI */
 386        WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL),
 387                UVD_JMI_CNTL__SOFT_RESET_MASK,
 388                ~UVD_JMI_CNTL__SOFT_RESET_MASK);
 389
 390        /* enable JPEG CGC */
 391        jpeg_v2_0_enable_clock_gating(adev);
 392
 393        /* enable power gating */
 394        r = jpeg_v2_0_enable_power_gating(adev);
 395        if (r)
 396                return r;
 397
 398        if (adev->pm.dpm_enabled)
 399                amdgpu_dpm_enable_jpeg(adev, false);
 400
 401        return 0;
 402}
 403
 404/**
 405 * jpeg_v2_0_dec_ring_get_rptr - get read pointer
 406 *
 407 * @ring: amdgpu_ring pointer
 408 *
 409 * Returns the current hardware read pointer
 410 */
 411static uint64_t jpeg_v2_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
 412{
 413        struct amdgpu_device *adev = ring->adev;
 414
 415        return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
 416}
 417
 418/**
 419 * jpeg_v2_0_dec_ring_get_wptr - get write pointer
 420 *
 421 * @ring: amdgpu_ring pointer
 422 *
 423 * Returns the current hardware write pointer
 424 */
 425static uint64_t jpeg_v2_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
 426{
 427        struct amdgpu_device *adev = ring->adev;
 428
 429        if (ring->use_doorbell)
 430                return adev->wb.wb[ring->wptr_offs];
 431        else
 432                return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
 433}
 434
 435/**
 436 * jpeg_v2_0_dec_ring_set_wptr - set write pointer
 437 *
 438 * @ring: amdgpu_ring pointer
 439 *
 440 * Commits the write pointer to the hardware
 441 */
 442static void jpeg_v2_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
 443{
 444        struct amdgpu_device *adev = ring->adev;
 445
 446        if (ring->use_doorbell) {
 447                adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
 448                WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
 449        } else {
 450                WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
 451        }
 452}
 453
 454/**
 455 * jpeg_v2_0_dec_ring_insert_start - insert a start command
 456 *
 457 * @ring: amdgpu_ring pointer
 458 *
 459 * Write a start command to the ring.
 460 */
 461void jpeg_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring)
 462{
 463        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 464                0, 0, PACKETJ_TYPE0));
 465        amdgpu_ring_write(ring, 0x68e04);
 466
 467        amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
 468                0, 0, PACKETJ_TYPE0));
 469        amdgpu_ring_write(ring, 0x80010000);
 470}
 471
 472/**
 473 * jpeg_v2_0_dec_ring_insert_end - insert a end command
 474 *
 475 * @ring: amdgpu_ring pointer
 476 *
 477 * Write a end command to the ring.
 478 */
 479void jpeg_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring)
 480{
 481        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 482                0, 0, PACKETJ_TYPE0));
 483        amdgpu_ring_write(ring, 0x68e04);
 484
 485        amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
 486                0, 0, PACKETJ_TYPE0));
 487        amdgpu_ring_write(ring, 0x00010000);
 488}
 489
 490/**
 491 * jpeg_v2_0_dec_ring_emit_fence - emit an fence & trap command
 492 *
 493 * @ring: amdgpu_ring pointer
 494 * @addr: address
 495 * @seq: sequence number
 496 * @flags: fence related flags
 497 *
 498 * Write a fence and a trap command to the ring.
 499 */
 500void jpeg_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
 501                                unsigned flags)
 502{
 503        WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
 504
 505        amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA0_INTERNAL_OFFSET,
 506                0, 0, PACKETJ_TYPE0));
 507        amdgpu_ring_write(ring, seq);
 508
 509        amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_DATA1_INTERNAL_OFFSET,
 510                0, 0, PACKETJ_TYPE0));
 511        amdgpu_ring_write(ring, seq);
 512
 513        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW_INTERNAL_OFFSET,
 514                0, 0, PACKETJ_TYPE0));
 515        amdgpu_ring_write(ring, lower_32_bits(addr));
 516
 517        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH_INTERNAL_OFFSET,
 518                0, 0, PACKETJ_TYPE0));
 519        amdgpu_ring_write(ring, upper_32_bits(addr));
 520
 521        amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
 522                0, 0, PACKETJ_TYPE0));
 523        amdgpu_ring_write(ring, 0x8);
 524
 525        amdgpu_ring_write(ring, PACKETJ(mmUVD_JPEG_GPCOM_CMD_INTERNAL_OFFSET,
 526                0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
 527        amdgpu_ring_write(ring, 0);
 528
 529        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 530                0, 0, PACKETJ_TYPE0));
 531        amdgpu_ring_write(ring, 0x3fbc);
 532
 533        amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
 534                0, 0, PACKETJ_TYPE0));
 535        amdgpu_ring_write(ring, 0x1);
 536
 537        amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
 538        amdgpu_ring_write(ring, 0);
 539}
 540
 541/**
 542 * jpeg_v2_0_dec_ring_emit_ib - execute indirect buffer
 543 *
 544 * @ring: amdgpu_ring pointer
 545 * @job: job to retrieve vmid from
 546 * @ib: indirect buffer to execute
 547 * @flags: unused
 548 *
 549 * Write ring commands to execute the indirect buffer.
 550 */
 551void jpeg_v2_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
 552                                struct amdgpu_job *job,
 553                                struct amdgpu_ib *ib,
 554                                uint32_t flags)
 555{
 556        unsigned vmid = AMDGPU_JOB_GET_VMID(job);
 557
 558        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
 559                0, 0, PACKETJ_TYPE0));
 560        amdgpu_ring_write(ring, (vmid | (vmid << 4)));
 561
 562        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
 563                0, 0, PACKETJ_TYPE0));
 564        amdgpu_ring_write(ring, (vmid | (vmid << 4)));
 565
 566        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
 567                0, 0, PACKETJ_TYPE0));
 568        amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
 569
 570        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET,
 571                0, 0, PACKETJ_TYPE0));
 572        amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
 573
 574        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_IB_SIZE_INTERNAL_OFFSET,
 575                0, 0, PACKETJ_TYPE0));
 576        amdgpu_ring_write(ring, ib->length_dw);
 577
 578        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW_INTERNAL_OFFSET,
 579                0, 0, PACKETJ_TYPE0));
 580        amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
 581
 582        amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH_INTERNAL_OFFSET,
 583                0, 0, PACKETJ_TYPE0));
 584        amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
 585
 586        amdgpu_ring_write(ring, PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
 587        amdgpu_ring_write(ring, 0);
 588
 589        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
 590                0, 0, PACKETJ_TYPE0));
 591        amdgpu_ring_write(ring, 0x01400200);
 592
 593        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
 594                0, 0, PACKETJ_TYPE0));
 595        amdgpu_ring_write(ring, 0x2);
 596
 597        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_STATUS_INTERNAL_OFFSET,
 598                0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
 599        amdgpu_ring_write(ring, 0x2);
 600}
 601
 602void jpeg_v2_0_dec_ring_emit_reg_wait(struct amdgpu_ring *ring, uint32_t reg,
 603                                uint32_t val, uint32_t mask)
 604{
 605        uint32_t reg_offset = (reg << 2);
 606
 607        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_COND_RD_TIMER_INTERNAL_OFFSET,
 608                0, 0, PACKETJ_TYPE0));
 609        amdgpu_ring_write(ring, 0x01400200);
 610
 611        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_RB_REF_DATA_INTERNAL_OFFSET,
 612                0, 0, PACKETJ_TYPE0));
 613        amdgpu_ring_write(ring, val);
 614
 615        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 616                0, 0, PACKETJ_TYPE0));
 617        if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
 618                amdgpu_ring_write(ring, 0);
 619                amdgpu_ring_write(ring,
 620                        PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
 621        } else {
 622                amdgpu_ring_write(ring, reg_offset);
 623                amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
 624                        0, 0, PACKETJ_TYPE3));
 625        }
 626        amdgpu_ring_write(ring, mask);
 627}
 628
 629void jpeg_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
 630                                unsigned vmid, uint64_t pd_addr)
 631{
 632        struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
 633        uint32_t data0, data1, mask;
 634
 635        pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
 636
 637        /* wait for register write */
 638        data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;
 639        data1 = lower_32_bits(pd_addr);
 640        mask = 0xffffffff;
 641        jpeg_v2_0_dec_ring_emit_reg_wait(ring, data0, data1, mask);
 642}
 643
 644void jpeg_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val)
 645{
 646        uint32_t reg_offset = (reg << 2);
 647
 648        amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 649                0, 0, PACKETJ_TYPE0));
 650        if (reg_offset >= 0x10000 && reg_offset <= 0x105ff) {
 651                amdgpu_ring_write(ring, 0);
 652                amdgpu_ring_write(ring,
 653                        PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
 654        } else {
 655                amdgpu_ring_write(ring, reg_offset);
 656                amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
 657                        0, 0, PACKETJ_TYPE0));
 658        }
 659        amdgpu_ring_write(ring, val);
 660}
 661
 662void jpeg_v2_0_dec_ring_nop(struct amdgpu_ring *ring, uint32_t count)
 663{
 664        int i;
 665
 666        WARN_ON(ring->wptr % 2 || count % 2);
 667
 668        for (i = 0; i < count / 2; i++) {
 669                amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
 670                amdgpu_ring_write(ring, 0);
 671        }
 672}
 673
 674static bool jpeg_v2_0_is_idle(void *handle)
 675{
 676        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 677
 678        return ((RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS) &
 679                UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
 680                UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
 681}
 682
 683static int jpeg_v2_0_wait_for_idle(void *handle)
 684{
 685        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 686        int ret;
 687
 688        ret = SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS, UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
 689                UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
 690
 691        return ret;
 692}
 693
 694static int jpeg_v2_0_set_clockgating_state(void *handle,
 695                                          enum amd_clockgating_state state)
 696{
 697        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 698        bool enable = (state == AMD_CG_STATE_GATE);
 699
 700        if (enable) {
 701                if (!jpeg_v2_0_is_idle(handle))
 702                        return -EBUSY;
 703                jpeg_v2_0_enable_clock_gating(adev);
 704        } else {
 705                jpeg_v2_0_disable_clock_gating(adev);
 706        }
 707
 708        return 0;
 709}
 710
 711static int jpeg_v2_0_set_powergating_state(void *handle,
 712                                        enum amd_powergating_state state)
 713{
 714        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 715        int ret;
 716
 717        if (state == adev->jpeg.cur_state)
 718                return 0;
 719
 720        if (state == AMD_PG_STATE_GATE)
 721                ret = jpeg_v2_0_stop(adev);
 722        else
 723                ret = jpeg_v2_0_start(adev);
 724
 725        if (!ret)
 726                adev->jpeg.cur_state = state;
 727
 728        return ret;
 729}
 730
 731static int jpeg_v2_0_set_interrupt_state(struct amdgpu_device *adev,
 732                                        struct amdgpu_irq_src *source,
 733                                        unsigned type,
 734                                        enum amdgpu_interrupt_state state)
 735{
 736        return 0;
 737}
 738
 739static int jpeg_v2_0_process_interrupt(struct amdgpu_device *adev,
 740                                      struct amdgpu_irq_src *source,
 741                                      struct amdgpu_iv_entry *entry)
 742{
 743        DRM_DEBUG("IH: JPEG TRAP\n");
 744
 745        switch (entry->src_id) {
 746        case VCN_2_0__SRCID__JPEG_DECODE:
 747                amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
 748                break;
 749        default:
 750                DRM_ERROR("Unhandled interrupt: %d %d\n",
 751                          entry->src_id, entry->src_data[0]);
 752                break;
 753        }
 754
 755        return 0;
 756}
 757
 758static const struct amd_ip_funcs jpeg_v2_0_ip_funcs = {
 759        .name = "jpeg_v2_0",
 760        .early_init = jpeg_v2_0_early_init,
 761        .late_init = NULL,
 762        .sw_init = jpeg_v2_0_sw_init,
 763        .sw_fini = jpeg_v2_0_sw_fini,
 764        .hw_init = jpeg_v2_0_hw_init,
 765        .hw_fini = jpeg_v2_0_hw_fini,
 766        .suspend = jpeg_v2_0_suspend,
 767        .resume = jpeg_v2_0_resume,
 768        .is_idle = jpeg_v2_0_is_idle,
 769        .wait_for_idle = jpeg_v2_0_wait_for_idle,
 770        .check_soft_reset = NULL,
 771        .pre_soft_reset = NULL,
 772        .soft_reset = NULL,
 773        .post_soft_reset = NULL,
 774        .set_clockgating_state = jpeg_v2_0_set_clockgating_state,
 775        .set_powergating_state = jpeg_v2_0_set_powergating_state,
 776};
 777
 778static const struct amdgpu_ring_funcs jpeg_v2_0_dec_ring_vm_funcs = {
 779        .type = AMDGPU_RING_TYPE_VCN_JPEG,
 780        .align_mask = 0xf,
 781        .vmhub = AMDGPU_MMHUB_0,
 782        .get_rptr = jpeg_v2_0_dec_ring_get_rptr,
 783        .get_wptr = jpeg_v2_0_dec_ring_get_wptr,
 784        .set_wptr = jpeg_v2_0_dec_ring_set_wptr,
 785        .emit_frame_size =
 786                SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 787                SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
 788                8 + /* jpeg_v2_0_dec_ring_emit_vm_flush */
 789                18 + 18 + /* jpeg_v2_0_dec_ring_emit_fence x2 vm fence */
 790                8 + 16,
 791        .emit_ib_size = 22, /* jpeg_v2_0_dec_ring_emit_ib */
 792        .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
 793        .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
 794        .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
 795        .test_ring = amdgpu_jpeg_dec_ring_test_ring,
 796        .test_ib = amdgpu_jpeg_dec_ring_test_ib,
 797        .insert_nop = jpeg_v2_0_dec_ring_nop,
 798        .insert_start = jpeg_v2_0_dec_ring_insert_start,
 799        .insert_end = jpeg_v2_0_dec_ring_insert_end,
 800        .pad_ib = amdgpu_ring_generic_pad_ib,
 801        .begin_use = amdgpu_jpeg_ring_begin_use,
 802        .end_use = amdgpu_jpeg_ring_end_use,
 803        .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
 804        .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
 805        .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
 806};
 807
 808static void jpeg_v2_0_set_dec_ring_funcs(struct amdgpu_device *adev)
 809{
 810        adev->jpeg.inst->ring_dec.funcs = &jpeg_v2_0_dec_ring_vm_funcs;
 811        DRM_INFO("JPEG decode is enabled in VM mode\n");
 812}
 813
 814static const struct amdgpu_irq_src_funcs jpeg_v2_0_irq_funcs = {
 815        .set = jpeg_v2_0_set_interrupt_state,
 816        .process = jpeg_v2_0_process_interrupt,
 817};
 818
 819static void jpeg_v2_0_set_irq_funcs(struct amdgpu_device *adev)
 820{
 821        adev->jpeg.inst->irq.num_types = 1;
 822        adev->jpeg.inst->irq.funcs = &jpeg_v2_0_irq_funcs;
 823}
 824
 825const struct amdgpu_ip_block_version jpeg_v2_0_ip_block =
 826{
 827                .type = AMD_IP_BLOCK_TYPE_JPEG,
 828                .major = 2,
 829                .minor = 0,
 830                .rev = 0,
 831                .funcs = &jpeg_v2_0_ip_funcs,
 832};
 833