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

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

DEFINITIONS

This source file includes following definitions.
  1. amdgpu_vcn_sw_init
  2. amdgpu_vcn_sw_fini
  3. amdgpu_vcn_suspend
  4. amdgpu_vcn_resume
  5. amdgpu_vcn_idle_work_handler
  6. amdgpu_vcn_ring_begin_use
  7. amdgpu_vcn_ring_end_use
  8. amdgpu_vcn_dec_ring_test_ring
  9. amdgpu_vcn_dec_send_msg
  10. amdgpu_vcn_dec_get_create_msg
  11. amdgpu_vcn_dec_get_destroy_msg
  12. amdgpu_vcn_dec_ring_test_ib
  13. amdgpu_vcn_enc_ring_test_ring
  14. amdgpu_vcn_enc_get_create_msg
  15. amdgpu_vcn_enc_get_destroy_msg
  16. amdgpu_vcn_enc_ring_test_ib
  17. amdgpu_vcn_jpeg_ring_test_ring
  18. amdgpu_vcn_jpeg_set_reg
  19. amdgpu_vcn_jpeg_ring_test_ib

   1 /*
   2  * Copyright 2016 Advanced Micro Devices, Inc.
   3  * All Rights Reserved.
   4  *
   5  * Permission is hereby granted, free of charge, to any person obtaining a
   6  * copy of this software and associated documentation files (the
   7  * "Software"), to deal in the Software without restriction, including
   8  * without limitation the rights to use, copy, modify, merge, publish,
   9  * distribute, sub license, and/or sell copies of the Software, and to
  10  * permit persons to whom the Software is furnished to do so, subject to
  11  * the following conditions:
  12  *
  13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  16  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  17  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  18  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  20  *
  21  * The above copyright notice and this permission notice (including the
  22  * next paragraph) shall be included in all copies or substantial portions
  23  * of the Software.
  24  *
  25  */
  26 
  27 #include <linux/firmware.h>
  28 #include <linux/module.h>
  29 #include <linux/pci.h>
  30 
  31 #include <drm/drm.h>
  32 
  33 #include "amdgpu.h"
  34 #include "amdgpu_pm.h"
  35 #include "amdgpu_vcn.h"
  36 #include "soc15d.h"
  37 #include "soc15_common.h"
  38 
  39 #include "vcn/vcn_1_0_offset.h"
  40 #include "vcn/vcn_1_0_sh_mask.h"
  41 
  42 /* 1 second timeout */
  43 #define VCN_IDLE_TIMEOUT        msecs_to_jiffies(1000)
  44 
  45 /* Firmware Names */
  46 #define FIRMWARE_RAVEN          "amdgpu/raven_vcn.bin"
  47 #define FIRMWARE_PICASSO        "amdgpu/picasso_vcn.bin"
  48 #define FIRMWARE_RAVEN2         "amdgpu/raven2_vcn.bin"
  49 #define FIRMWARE_ARCTURUS       "amdgpu/arcturus_vcn.bin"
  50 #define FIRMWARE_RENOIR         "amdgpu/renoir_vcn.bin"
  51 #define FIRMWARE_NAVI10         "amdgpu/navi10_vcn.bin"
  52 #define FIRMWARE_NAVI14         "amdgpu/navi14_vcn.bin"
  53 #define FIRMWARE_NAVI12         "amdgpu/navi12_vcn.bin"
  54 
  55 MODULE_FIRMWARE(FIRMWARE_RAVEN);
  56 MODULE_FIRMWARE(FIRMWARE_PICASSO);
  57 MODULE_FIRMWARE(FIRMWARE_RAVEN2);
  58 MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
  59 MODULE_FIRMWARE(FIRMWARE_RENOIR);
  60 MODULE_FIRMWARE(FIRMWARE_NAVI10);
  61 MODULE_FIRMWARE(FIRMWARE_NAVI14);
  62 MODULE_FIRMWARE(FIRMWARE_NAVI12);
  63 
  64 static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
  65 
  66 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
  67 {
  68         unsigned long bo_size;
  69         const char *fw_name;
  70         const struct common_firmware_header *hdr;
  71         unsigned char fw_check;
  72         int i, r;
  73 
  74         INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
  75 
  76         switch (adev->asic_type) {
  77         case CHIP_RAVEN:
  78                 if (adev->rev_id >= 8)
  79                         fw_name = FIRMWARE_RAVEN2;
  80                 else if (adev->pdev->device == 0x15d8)
  81                         fw_name = FIRMWARE_PICASSO;
  82                 else
  83                         fw_name = FIRMWARE_RAVEN;
  84                 break;
  85         case CHIP_ARCTURUS:
  86                 fw_name = FIRMWARE_ARCTURUS;
  87                 break;
  88         case CHIP_RENOIR:
  89                 fw_name = FIRMWARE_RENOIR;
  90                 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
  91                     (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
  92                         adev->vcn.indirect_sram = true;
  93                 break;
  94         case CHIP_NAVI10:
  95                 fw_name = FIRMWARE_NAVI10;
  96                 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
  97                     (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
  98                         adev->vcn.indirect_sram = true;
  99                 break;
 100         case CHIP_NAVI14:
 101                 fw_name = FIRMWARE_NAVI14;
 102                 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 103                     (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 104                         adev->vcn.indirect_sram = true;
 105                 break;
 106         case CHIP_NAVI12:
 107                 fw_name = FIRMWARE_NAVI12;
 108                 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
 109                     (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
 110                         adev->vcn.indirect_sram = true;
 111                 break;
 112         default:
 113                 return -EINVAL;
 114         }
 115 
 116         r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
 117         if (r) {
 118                 dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
 119                         fw_name);
 120                 return r;
 121         }
 122 
 123         r = amdgpu_ucode_validate(adev->vcn.fw);
 124         if (r) {
 125                 dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
 126                         fw_name);
 127                 release_firmware(adev->vcn.fw);
 128                 adev->vcn.fw = NULL;
 129                 return r;
 130         }
 131 
 132         hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
 133         adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 134 
 135         /* Bit 20-23, it is encode major and non-zero for new naming convention.
 136          * This field is part of version minor and DRM_DISABLED_FLAG in old naming
 137          * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
 138          * is zero in old naming convention, this field is always zero so far.
 139          * These four bits are used to tell which naming convention is present.
 140          */
 141         fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
 142         if (fw_check) {
 143                 unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
 144 
 145                 fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
 146                 enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
 147                 enc_major = fw_check;
 148                 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
 149                 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
 150                 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
 151                         enc_major, enc_minor, dec_ver, vep, fw_rev);
 152         } else {
 153                 unsigned int version_major, version_minor, family_id;
 154 
 155                 family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
 156                 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
 157                 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
 158                 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
 159                         version_major, version_minor, family_id);
 160         }
 161 
 162         bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
 163         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
 164                 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
 165 
 166         for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 167                 if (adev->vcn.harvest_config & (1 << i))
 168                         continue;
 169 
 170                 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
 171                                                 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo,
 172                                                 &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr);
 173                 if (r) {
 174                         dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
 175                         return r;
 176                 }
 177         }
 178 
 179         if (adev->vcn.indirect_sram) {
 180                 r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
 181                             AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.dpg_sram_bo,
 182                             &adev->vcn.dpg_sram_gpu_addr, &adev->vcn.dpg_sram_cpu_addr);
 183                 if (r) {
 184                         dev_err(adev->dev, "(%d) failed to allocate DPG bo\n", r);
 185                         return r;
 186                 }
 187         }
 188 
 189         return 0;
 190 }
 191 
 192 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
 193 {
 194         int i, j;
 195 
 196         if (adev->vcn.indirect_sram) {
 197                 amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo,
 198                                       &adev->vcn.dpg_sram_gpu_addr,
 199                                       (void **)&adev->vcn.dpg_sram_cpu_addr);
 200         }
 201 
 202         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
 203                 if (adev->vcn.harvest_config & (1 << j))
 204                         continue;
 205                 kvfree(adev->vcn.inst[j].saved_bo);
 206 
 207                 amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo,
 208                                           &adev->vcn.inst[j].gpu_addr,
 209                                           (void **)&adev->vcn.inst[j].cpu_addr);
 210 
 211                 amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec);
 212 
 213                 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
 214                         amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]);
 215 
 216                 amdgpu_ring_fini(&adev->vcn.inst[j].ring_jpeg);
 217         }
 218 
 219         release_firmware(adev->vcn.fw);
 220 
 221         return 0;
 222 }
 223 
 224 int amdgpu_vcn_suspend(struct amdgpu_device *adev)
 225 {
 226         unsigned size;
 227         void *ptr;
 228         int i;
 229 
 230         cancel_delayed_work_sync(&adev->vcn.idle_work);
 231 
 232         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 233                 if (adev->vcn.harvest_config & (1 << i))
 234                         continue;
 235                 if (adev->vcn.inst[i].vcpu_bo == NULL)
 236                         return 0;
 237 
 238                 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
 239                 ptr = adev->vcn.inst[i].cpu_addr;
 240 
 241                 adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL);
 242                 if (!adev->vcn.inst[i].saved_bo)
 243                         return -ENOMEM;
 244 
 245                 memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
 246         }
 247         return 0;
 248 }
 249 
 250 int amdgpu_vcn_resume(struct amdgpu_device *adev)
 251 {
 252         unsigned size;
 253         void *ptr;
 254         int i;
 255 
 256         for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
 257                 if (adev->vcn.harvest_config & (1 << i))
 258                         continue;
 259                 if (adev->vcn.inst[i].vcpu_bo == NULL)
 260                         return -EINVAL;
 261 
 262                 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
 263                 ptr = adev->vcn.inst[i].cpu_addr;
 264 
 265                 if (adev->vcn.inst[i].saved_bo != NULL) {
 266                         memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
 267                         kvfree(adev->vcn.inst[i].saved_bo);
 268                         adev->vcn.inst[i].saved_bo = NULL;
 269                 } else {
 270                         const struct common_firmware_header *hdr;
 271                         unsigned offset;
 272 
 273                         hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
 274                         if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
 275                                 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
 276                                 memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
 277                                             le32_to_cpu(hdr->ucode_size_bytes));
 278                                 size -= le32_to_cpu(hdr->ucode_size_bytes);
 279                                 ptr += le32_to_cpu(hdr->ucode_size_bytes);
 280                         }
 281                         memset_io(ptr, 0, size);
 282                 }
 283         }
 284         return 0;
 285 }
 286 
 287 static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
 288 {
 289         struct amdgpu_device *adev =
 290                 container_of(work, struct amdgpu_device, vcn.idle_work.work);
 291         unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
 292         unsigned int i, j;
 293 
 294         for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
 295                 if (adev->vcn.harvest_config & (1 << j))
 296                         continue;
 297                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 298                         fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
 299                 }
 300 
 301                 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)    {
 302                         struct dpg_pause_state new_state;
 303 
 304                         if (fence[j])
 305                                 new_state.fw_based = VCN_DPG_STATE__PAUSE;
 306                         else
 307                                 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
 308 
 309                         if (amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_jpeg))
 310                                 new_state.jpeg = VCN_DPG_STATE__PAUSE;
 311                         else
 312                                 new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
 313 
 314                         adev->vcn.pause_dpg_mode(adev, &new_state);
 315                 }
 316 
 317                 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_jpeg);
 318                 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);
 319                 fences += fence[j];
 320         }
 321 
 322         if (fences == 0) {
 323                 amdgpu_gfx_off_ctrl(adev, true);
 324                 if (adev->asic_type < CHIP_ARCTURUS && adev->pm.dpm_enabled)
 325                         amdgpu_dpm_enable_uvd(adev, false);
 326                 else
 327                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 328                                                                AMD_PG_STATE_GATE);
 329         } else {
 330                 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
 331         }
 332 }
 333 
 334 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
 335 {
 336         struct amdgpu_device *adev = ring->adev;
 337         bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
 338 
 339         if (set_clocks) {
 340                 amdgpu_gfx_off_ctrl(adev, false);
 341                 if (adev->asic_type < CHIP_ARCTURUS && adev->pm.dpm_enabled)
 342                         amdgpu_dpm_enable_uvd(adev, true);
 343                 else
 344                         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 345                                                                AMD_PG_STATE_UNGATE);
 346         }
 347 
 348         if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)    {
 349                 struct dpg_pause_state new_state;
 350                 unsigned int fences = 0;
 351                 unsigned int i;
 352 
 353                 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
 354                         fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
 355                 }
 356                 if (fences)
 357                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
 358                 else
 359                         new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
 360 
 361                 if (amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_jpeg))
 362                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
 363                 else
 364                         new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
 365 
 366                 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
 367                         new_state.fw_based = VCN_DPG_STATE__PAUSE;
 368                 else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
 369                         new_state.jpeg = VCN_DPG_STATE__PAUSE;
 370 
 371                 adev->vcn.pause_dpg_mode(adev, &new_state);
 372         }
 373 }
 374 
 375 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 376 {
 377         schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
 378 }
 379 
 380 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
 381 {
 382         struct amdgpu_device *adev = ring->adev;
 383         uint32_t tmp = 0;
 384         unsigned i;
 385         int r;
 386 
 387         WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD);
 388         r = amdgpu_ring_alloc(ring, 3);
 389         if (r)
 390                 return r;
 391         amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
 392         amdgpu_ring_write(ring, 0xDEADBEEF);
 393         amdgpu_ring_commit(ring);
 394         for (i = 0; i < adev->usec_timeout; i++) {
 395                 tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9);
 396                 if (tmp == 0xDEADBEEF)
 397                         break;
 398                 udelay(1);
 399         }
 400 
 401         if (i >= adev->usec_timeout)
 402                 r = -ETIMEDOUT;
 403 
 404         return r;
 405 }
 406 
 407 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
 408                                    struct amdgpu_bo *bo,
 409                                    struct dma_fence **fence)
 410 {
 411         struct amdgpu_device *adev = ring->adev;
 412         struct dma_fence *f = NULL;
 413         struct amdgpu_job *job;
 414         struct amdgpu_ib *ib;
 415         uint64_t addr;
 416         int i, r;
 417 
 418         r = amdgpu_job_alloc_with_ib(adev, 64, &job);
 419         if (r)
 420                 goto err;
 421 
 422         ib = &job->ibs[0];
 423         addr = amdgpu_bo_gpu_offset(bo);
 424         ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
 425         ib->ptr[1] = addr;
 426         ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
 427         ib->ptr[3] = addr >> 32;
 428         ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
 429         ib->ptr[5] = 0;
 430         for (i = 6; i < 16; i += 2) {
 431                 ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
 432                 ib->ptr[i+1] = 0;
 433         }
 434         ib->length_dw = 16;
 435 
 436         r = amdgpu_job_submit_direct(job, ring, &f);
 437         if (r)
 438                 goto err_free;
 439 
 440         amdgpu_bo_fence(bo, f, false);
 441         amdgpu_bo_unreserve(bo);
 442         amdgpu_bo_unref(&bo);
 443 
 444         if (fence)
 445                 *fence = dma_fence_get(f);
 446         dma_fence_put(f);
 447 
 448         return 0;
 449 
 450 err_free:
 451         amdgpu_job_free(job);
 452 
 453 err:
 454         amdgpu_bo_unreserve(bo);
 455         amdgpu_bo_unref(&bo);
 456         return r;
 457 }
 458 
 459 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
 460                               struct dma_fence **fence)
 461 {
 462         struct amdgpu_device *adev = ring->adev;
 463         struct amdgpu_bo *bo = NULL;
 464         uint32_t *msg;
 465         int r, i;
 466 
 467         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
 468                                       AMDGPU_GEM_DOMAIN_VRAM,
 469                                       &bo, NULL, (void **)&msg);
 470         if (r)
 471                 return r;
 472 
 473         msg[0] = cpu_to_le32(0x00000028);
 474         msg[1] = cpu_to_le32(0x00000038);
 475         msg[2] = cpu_to_le32(0x00000001);
 476         msg[3] = cpu_to_le32(0x00000000);
 477         msg[4] = cpu_to_le32(handle);
 478         msg[5] = cpu_to_le32(0x00000000);
 479         msg[6] = cpu_to_le32(0x00000001);
 480         msg[7] = cpu_to_le32(0x00000028);
 481         msg[8] = cpu_to_le32(0x00000010);
 482         msg[9] = cpu_to_le32(0x00000000);
 483         msg[10] = cpu_to_le32(0x00000007);
 484         msg[11] = cpu_to_le32(0x00000000);
 485         msg[12] = cpu_to_le32(0x00000780);
 486         msg[13] = cpu_to_le32(0x00000440);
 487         for (i = 14; i < 1024; ++i)
 488                 msg[i] = cpu_to_le32(0x0);
 489 
 490         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
 491 }
 492 
 493 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
 494                                struct dma_fence **fence)
 495 {
 496         struct amdgpu_device *adev = ring->adev;
 497         struct amdgpu_bo *bo = NULL;
 498         uint32_t *msg;
 499         int r, i;
 500 
 501         r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
 502                                       AMDGPU_GEM_DOMAIN_VRAM,
 503                                       &bo, NULL, (void **)&msg);
 504         if (r)
 505                 return r;
 506 
 507         msg[0] = cpu_to_le32(0x00000028);
 508         msg[1] = cpu_to_le32(0x00000018);
 509         msg[2] = cpu_to_le32(0x00000000);
 510         msg[3] = cpu_to_le32(0x00000002);
 511         msg[4] = cpu_to_le32(handle);
 512         msg[5] = cpu_to_le32(0x00000000);
 513         for (i = 6; i < 1024; ++i)
 514                 msg[i] = cpu_to_le32(0x0);
 515 
 516         return amdgpu_vcn_dec_send_msg(ring, bo, fence);
 517 }
 518 
 519 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 520 {
 521         struct dma_fence *fence;
 522         long r;
 523 
 524         r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
 525         if (r)
 526                 goto error;
 527 
 528         r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
 529         if (r)
 530                 goto error;
 531 
 532         r = dma_fence_wait_timeout(fence, false, timeout);
 533         if (r == 0)
 534                 r = -ETIMEDOUT;
 535         else if (r > 0)
 536                 r = 0;
 537 
 538         dma_fence_put(fence);
 539 error:
 540         return r;
 541 }
 542 
 543 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
 544 {
 545         struct amdgpu_device *adev = ring->adev;
 546         uint32_t rptr;
 547         unsigned i;
 548         int r;
 549 
 550         r = amdgpu_ring_alloc(ring, 16);
 551         if (r)
 552                 return r;
 553 
 554         rptr = amdgpu_ring_get_rptr(ring);
 555 
 556         amdgpu_ring_write(ring, VCN_ENC_CMD_END);
 557         amdgpu_ring_commit(ring);
 558 
 559         for (i = 0; i < adev->usec_timeout; i++) {
 560                 if (amdgpu_ring_get_rptr(ring) != rptr)
 561                         break;
 562                 udelay(1);
 563         }
 564 
 565         if (i >= adev->usec_timeout)
 566                 r = -ETIMEDOUT;
 567 
 568         return r;
 569 }
 570 
 571 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
 572                                          struct amdgpu_bo *bo,
 573                                          struct dma_fence **fence)
 574 {
 575         const unsigned ib_size_dw = 16;
 576         struct amdgpu_job *job;
 577         struct amdgpu_ib *ib;
 578         struct dma_fence *f = NULL;
 579         uint64_t addr;
 580         int i, r;
 581 
 582         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
 583         if (r)
 584                 return r;
 585 
 586         ib = &job->ibs[0];
 587         addr = amdgpu_bo_gpu_offset(bo);
 588 
 589         ib->length_dw = 0;
 590         ib->ptr[ib->length_dw++] = 0x00000018;
 591         ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
 592         ib->ptr[ib->length_dw++] = handle;
 593         ib->ptr[ib->length_dw++] = upper_32_bits(addr);
 594         ib->ptr[ib->length_dw++] = addr;
 595         ib->ptr[ib->length_dw++] = 0x0000000b;
 596 
 597         ib->ptr[ib->length_dw++] = 0x00000014;
 598         ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
 599         ib->ptr[ib->length_dw++] = 0x0000001c;
 600         ib->ptr[ib->length_dw++] = 0x00000000;
 601         ib->ptr[ib->length_dw++] = 0x00000000;
 602 
 603         ib->ptr[ib->length_dw++] = 0x00000008;
 604         ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
 605 
 606         for (i = ib->length_dw; i < ib_size_dw; ++i)
 607                 ib->ptr[i] = 0x0;
 608 
 609         r = amdgpu_job_submit_direct(job, ring, &f);
 610         if (r)
 611                 goto err;
 612 
 613         if (fence)
 614                 *fence = dma_fence_get(f);
 615         dma_fence_put(f);
 616 
 617         return 0;
 618 
 619 err:
 620         amdgpu_job_free(job);
 621         return r;
 622 }
 623 
 624 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
 625                                           struct amdgpu_bo *bo,
 626                                           struct dma_fence **fence)
 627 {
 628         const unsigned ib_size_dw = 16;
 629         struct amdgpu_job *job;
 630         struct amdgpu_ib *ib;
 631         struct dma_fence *f = NULL;
 632         uint64_t addr;
 633         int i, r;
 634 
 635         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
 636         if (r)
 637                 return r;
 638 
 639         ib = &job->ibs[0];
 640         addr = amdgpu_bo_gpu_offset(bo);
 641 
 642         ib->length_dw = 0;
 643         ib->ptr[ib->length_dw++] = 0x00000018;
 644         ib->ptr[ib->length_dw++] = 0x00000001;
 645         ib->ptr[ib->length_dw++] = handle;
 646         ib->ptr[ib->length_dw++] = upper_32_bits(addr);
 647         ib->ptr[ib->length_dw++] = addr;
 648         ib->ptr[ib->length_dw++] = 0x0000000b;
 649 
 650         ib->ptr[ib->length_dw++] = 0x00000014;
 651         ib->ptr[ib->length_dw++] = 0x00000002;
 652         ib->ptr[ib->length_dw++] = 0x0000001c;
 653         ib->ptr[ib->length_dw++] = 0x00000000;
 654         ib->ptr[ib->length_dw++] = 0x00000000;
 655 
 656         ib->ptr[ib->length_dw++] = 0x00000008;
 657         ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
 658 
 659         for (i = ib->length_dw; i < ib_size_dw; ++i)
 660                 ib->ptr[i] = 0x0;
 661 
 662         r = amdgpu_job_submit_direct(job, ring, &f);
 663         if (r)
 664                 goto err;
 665 
 666         if (fence)
 667                 *fence = dma_fence_get(f);
 668         dma_fence_put(f);
 669 
 670         return 0;
 671 
 672 err:
 673         amdgpu_job_free(job);
 674         return r;
 675 }
 676 
 677 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 678 {
 679         struct dma_fence *fence = NULL;
 680         struct amdgpu_bo *bo = NULL;
 681         long r;
 682 
 683         r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
 684                                       AMDGPU_GEM_DOMAIN_VRAM,
 685                                       &bo, NULL, NULL);
 686         if (r)
 687                 return r;
 688 
 689         r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
 690         if (r)
 691                 goto error;
 692 
 693         r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
 694         if (r)
 695                 goto error;
 696 
 697         r = dma_fence_wait_timeout(fence, false, timeout);
 698         if (r == 0)
 699                 r = -ETIMEDOUT;
 700         else if (r > 0)
 701                 r = 0;
 702 
 703 error:
 704         dma_fence_put(fence);
 705         amdgpu_bo_unreserve(bo);
 706         amdgpu_bo_unref(&bo);
 707         return r;
 708 }
 709 
 710 int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
 711 {
 712         struct amdgpu_device *adev = ring->adev;
 713         uint32_t tmp = 0;
 714         unsigned i;
 715         int r;
 716 
 717         WREG32(adev->vcn.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD);
 718         r = amdgpu_ring_alloc(ring, 3);
 719         if (r)
 720                 return r;
 721 
 722         amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.jpeg_pitch, 0));
 723         amdgpu_ring_write(ring, 0xDEADBEEF);
 724         amdgpu_ring_commit(ring);
 725 
 726         for (i = 0; i < adev->usec_timeout; i++) {
 727                 tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch);
 728                 if (tmp == 0xDEADBEEF)
 729                         break;
 730                 udelay(1);
 731         }
 732 
 733         if (i >= adev->usec_timeout)
 734                 r = -ETIMEDOUT;
 735 
 736         return r;
 737 }
 738 
 739 static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle,
 740                 struct dma_fence **fence)
 741 {
 742         struct amdgpu_device *adev = ring->adev;
 743         struct amdgpu_job *job;
 744         struct amdgpu_ib *ib;
 745         struct dma_fence *f = NULL;
 746         const unsigned ib_size_dw = 16;
 747         int i, r;
 748 
 749         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
 750         if (r)
 751                 return r;
 752 
 753         ib = &job->ibs[0];
 754 
 755         ib->ptr[0] = PACKETJ(adev->vcn.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0);
 756         ib->ptr[1] = 0xDEADBEEF;
 757         for (i = 2; i < 16; i += 2) {
 758                 ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
 759                 ib->ptr[i+1] = 0;
 760         }
 761         ib->length_dw = 16;
 762 
 763         r = amdgpu_job_submit_direct(job, ring, &f);
 764         if (r)
 765                 goto err;
 766 
 767         if (fence)
 768                 *fence = dma_fence_get(f);
 769         dma_fence_put(f);
 770 
 771         return 0;
 772 
 773 err:
 774         amdgpu_job_free(job);
 775         return r;
 776 }
 777 
 778 int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
 779 {
 780         struct amdgpu_device *adev = ring->adev;
 781         uint32_t tmp = 0;
 782         unsigned i;
 783         struct dma_fence *fence = NULL;
 784         long r = 0;
 785 
 786         r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence);
 787         if (r)
 788                 goto error;
 789 
 790         r = dma_fence_wait_timeout(fence, false, timeout);
 791         if (r == 0) {
 792                 r = -ETIMEDOUT;
 793                 goto error;
 794         } else if (r < 0) {
 795                 goto error;
 796         } else {
 797                 r = 0;
 798         }
 799 
 800         for (i = 0; i < adev->usec_timeout; i++) {
 801                 tmp = RREG32(adev->vcn.inst[ring->me].external.jpeg_pitch);
 802                 if (tmp == 0xDEADBEEF)
 803                         break;
 804                 udelay(1);
 805         }
 806 
 807         if (i >= adev->usec_timeout)
 808                 r = -ETIMEDOUT;
 809 
 810         dma_fence_put(fence);
 811 error:
 812         return r;
 813 }

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