LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/amdgpu - amdgpu_jpeg.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 100 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2019 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 "amdgpu.h"
      28             : #include "amdgpu_jpeg.h"
      29             : #include "amdgpu_pm.h"
      30             : #include "soc15d.h"
      31             : #include "soc15_common.h"
      32             : 
      33             : #define JPEG_IDLE_TIMEOUT       msecs_to_jiffies(1000)
      34             : 
      35             : static void amdgpu_jpeg_idle_work_handler(struct work_struct *work);
      36             : 
      37           0 : int amdgpu_jpeg_sw_init(struct amdgpu_device *adev)
      38             : {
      39           0 :         INIT_DELAYED_WORK(&adev->jpeg.idle_work, amdgpu_jpeg_idle_work_handler);
      40           0 :         mutex_init(&adev->jpeg.jpeg_pg_lock);
      41           0 :         atomic_set(&adev->jpeg.total_submission_cnt, 0);
      42             : 
      43           0 :         return 0;
      44             : }
      45             : 
      46           0 : int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev)
      47             : {
      48             :         int i;
      49             : 
      50           0 :         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
      51           0 :                 if (adev->jpeg.harvest_config & (1 << i))
      52           0 :                         continue;
      53             : 
      54           0 :                 amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec);
      55             :         }
      56             : 
      57           0 :         mutex_destroy(&adev->jpeg.jpeg_pg_lock);
      58             : 
      59           0 :         return 0;
      60             : }
      61             : 
      62           0 : int amdgpu_jpeg_suspend(struct amdgpu_device *adev)
      63             : {
      64           0 :         cancel_delayed_work_sync(&adev->jpeg.idle_work);
      65             : 
      66           0 :         return 0;
      67             : }
      68             : 
      69           0 : int amdgpu_jpeg_resume(struct amdgpu_device *adev)
      70             : {
      71           0 :         return 0;
      72             : }
      73             : 
      74           0 : static void amdgpu_jpeg_idle_work_handler(struct work_struct *work)
      75             : {
      76           0 :         struct amdgpu_device *adev =
      77           0 :                 container_of(work, struct amdgpu_device, jpeg.idle_work.work);
      78           0 :         unsigned int fences = 0;
      79             :         unsigned int i;
      80             : 
      81           0 :         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
      82           0 :                 if (adev->jpeg.harvest_config & (1 << i))
      83           0 :                         continue;
      84             : 
      85           0 :                 fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec);
      86             :         }
      87             : 
      88           0 :         if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt))
      89           0 :                 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
      90             :                                                        AMD_PG_STATE_GATE);
      91             :         else
      92           0 :                 schedule_delayed_work(&adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT);
      93           0 : }
      94             : 
      95           0 : void amdgpu_jpeg_ring_begin_use(struct amdgpu_ring *ring)
      96             : {
      97           0 :         struct amdgpu_device *adev = ring->adev;
      98             : 
      99           0 :         atomic_inc(&adev->jpeg.total_submission_cnt);
     100           0 :         cancel_delayed_work_sync(&adev->jpeg.idle_work);
     101             : 
     102           0 :         mutex_lock(&adev->jpeg.jpeg_pg_lock);
     103           0 :         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
     104             :                                                        AMD_PG_STATE_UNGATE);
     105           0 :         mutex_unlock(&adev->jpeg.jpeg_pg_lock);
     106           0 : }
     107             : 
     108           0 : void amdgpu_jpeg_ring_end_use(struct amdgpu_ring *ring)
     109             : {
     110           0 :         atomic_dec(&ring->adev->jpeg.total_submission_cnt);
     111           0 :         schedule_delayed_work(&ring->adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT);
     112           0 : }
     113             : 
     114           0 : int amdgpu_jpeg_dec_ring_test_ring(struct amdgpu_ring *ring)
     115             : {
     116           0 :         struct amdgpu_device *adev = ring->adev;
     117           0 :         uint32_t tmp = 0;
     118             :         unsigned i;
     119             :         int r;
     120             : 
     121           0 :         WREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD);
     122           0 :         r = amdgpu_ring_alloc(ring, 3);
     123           0 :         if (r)
     124             :                 return r;
     125             : 
     126           0 :         amdgpu_ring_write(ring, PACKET0(adev->jpeg.internal.jpeg_pitch, 0));
     127           0 :         amdgpu_ring_write(ring, 0xDEADBEEF);
     128           0 :         amdgpu_ring_commit(ring);
     129             : 
     130           0 :         for (i = 0; i < adev->usec_timeout; i++) {
     131           0 :                 tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
     132           0 :                 if (tmp == 0xDEADBEEF)
     133             :                         break;
     134           0 :                 udelay(1);
     135             :         }
     136             : 
     137           0 :         if (i >= adev->usec_timeout)
     138           0 :                 r = -ETIMEDOUT;
     139             : 
     140             :         return r;
     141             : }
     142             : 
     143           0 : static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,
     144             :                 struct dma_fence **fence)
     145             : {
     146           0 :         struct amdgpu_device *adev = ring->adev;
     147             :         struct amdgpu_job *job;
     148             :         struct amdgpu_ib *ib;
     149           0 :         struct dma_fence *f = NULL;
     150           0 :         const unsigned ib_size_dw = 16;
     151             :         int i, r;
     152             : 
     153           0 :         r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
     154             :                                         AMDGPU_IB_POOL_DIRECT, &job);
     155           0 :         if (r)
     156             :                 return r;
     157             : 
     158           0 :         ib = &job->ibs[0];
     159             : 
     160           0 :         ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0);
     161           0 :         ib->ptr[1] = 0xDEADBEEF;
     162           0 :         for (i = 2; i < 16; i += 2) {
     163           0 :                 ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
     164           0 :                 ib->ptr[i+1] = 0;
     165             :         }
     166           0 :         ib->length_dw = 16;
     167             : 
     168           0 :         r = amdgpu_job_submit_direct(job, ring, &f);
     169           0 :         if (r)
     170             :                 goto err;
     171             : 
     172           0 :         if (fence)
     173           0 :                 *fence = dma_fence_get(f);
     174           0 :         dma_fence_put(f);
     175             : 
     176             :         return 0;
     177             : 
     178             : err:
     179           0 :         amdgpu_job_free(job);
     180             :         return r;
     181             : }
     182             : 
     183           0 : int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
     184             : {
     185           0 :         struct amdgpu_device *adev = ring->adev;
     186           0 :         uint32_t tmp = 0;
     187             :         unsigned i;
     188           0 :         struct dma_fence *fence = NULL;
     189           0 :         long r = 0;
     190             : 
     191           0 :         r = amdgpu_jpeg_dec_set_reg(ring, 1, &fence);
     192           0 :         if (r)
     193             :                 goto error;
     194             : 
     195           0 :         r = dma_fence_wait_timeout(fence, false, timeout);
     196           0 :         if (r == 0) {
     197             :                 r = -ETIMEDOUT;
     198             :                 goto error;
     199           0 :         } else if (r < 0) {
     200             :                 goto error;
     201             :         } else {
     202             :                 r = 0;
     203             :         }
     204             : 
     205           0 :         for (i = 0; i < adev->usec_timeout; i++) {
     206           0 :                 tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
     207           0 :                 if (tmp == 0xDEADBEEF)
     208             :                         break;
     209           0 :                 udelay(1);
     210             :         }
     211             : 
     212           0 :         if (i >= adev->usec_timeout)
     213           0 :                 r = -ETIMEDOUT;
     214             : 
     215           0 :         dma_fence_put(fence);
     216             : error:
     217           0 :         return r;
     218             : }
     219             : 
     220           0 : int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
     221             :                                 struct amdgpu_irq_src *source,
     222             :                                 struct amdgpu_iv_entry *entry)
     223             : {
     224           0 :         struct ras_common_if *ras_if = adev->jpeg.ras_if;
     225           0 :         struct ras_dispatch_if ih_data = {
     226             :                 .entry = entry,
     227             :         };
     228             : 
     229           0 :         if (!ras_if)
     230             :                 return 0;
     231             : 
     232           0 :         ih_data.head = *ras_if;
     233           0 :         amdgpu_ras_interrupt_dispatch(adev, &ih_data);
     234             : 
     235           0 :         return 0;
     236             : }

Generated by: LCOV version 1.14