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