Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Advanced Micro Devices, Inc.
0003  * All Rights Reserved.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the
0007  * "Software"), to deal in the Software without restriction, including
0008  * without limitation the rights to use, copy, modify, merge, publish,
0009  * distribute, sub license, and/or sell copies of the Software, and to
0010  * permit persons to whom the Software is furnished to do so, subject to
0011  * the following conditions:
0012  *
0013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0014  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0015  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0016  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0017  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0018  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0019  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0020  *
0021  * The above copyright notice and this permission notice (including the
0022  * next paragraph) shall be included in all copies or substantial portions
0023  * of the Software.
0024  *
0025  */
0026 
0027 #include "amdgpu.h"
0028 #include "amdgpu_jpeg.h"
0029 #include "amdgpu_pm.h"
0030 #include "soc15d.h"
0031 #include "soc15_common.h"
0032 
0033 #define JPEG_IDLE_TIMEOUT   msecs_to_jiffies(1000)
0034 
0035 static void amdgpu_jpeg_idle_work_handler(struct work_struct *work);
0036 
0037 int amdgpu_jpeg_sw_init(struct amdgpu_device *adev)
0038 {
0039     INIT_DELAYED_WORK(&adev->jpeg.idle_work, amdgpu_jpeg_idle_work_handler);
0040     mutex_init(&adev->jpeg.jpeg_pg_lock);
0041     atomic_set(&adev->jpeg.total_submission_cnt, 0);
0042 
0043     return 0;
0044 }
0045 
0046 int amdgpu_jpeg_sw_fini(struct amdgpu_device *adev)
0047 {
0048     int i;
0049 
0050     for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
0051         if (adev->jpeg.harvest_config & (1 << i))
0052             continue;
0053 
0054         amdgpu_ring_fini(&adev->jpeg.inst[i].ring_dec);
0055     }
0056 
0057     mutex_destroy(&adev->jpeg.jpeg_pg_lock);
0058 
0059     return 0;
0060 }
0061 
0062 int amdgpu_jpeg_suspend(struct amdgpu_device *adev)
0063 {
0064     cancel_delayed_work_sync(&adev->jpeg.idle_work);
0065 
0066     return 0;
0067 }
0068 
0069 int amdgpu_jpeg_resume(struct amdgpu_device *adev)
0070 {
0071     return 0;
0072 }
0073 
0074 static void amdgpu_jpeg_idle_work_handler(struct work_struct *work)
0075 {
0076     struct amdgpu_device *adev =
0077         container_of(work, struct amdgpu_device, jpeg.idle_work.work);
0078     unsigned int fences = 0;
0079     unsigned int i;
0080 
0081     for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
0082         if (adev->jpeg.harvest_config & (1 << i))
0083             continue;
0084 
0085         fences += amdgpu_fence_count_emitted(&adev->jpeg.inst[i].ring_dec);
0086     }
0087 
0088     if (!fences && !atomic_read(&adev->jpeg.total_submission_cnt))
0089         amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
0090                                AMD_PG_STATE_GATE);
0091     else
0092         schedule_delayed_work(&adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT);
0093 }
0094 
0095 void amdgpu_jpeg_ring_begin_use(struct amdgpu_ring *ring)
0096 {
0097     struct amdgpu_device *adev = ring->adev;
0098 
0099     atomic_inc(&adev->jpeg.total_submission_cnt);
0100     cancel_delayed_work_sync(&adev->jpeg.idle_work);
0101 
0102     mutex_lock(&adev->jpeg.jpeg_pg_lock);
0103     amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
0104                                AMD_PG_STATE_UNGATE);
0105     mutex_unlock(&adev->jpeg.jpeg_pg_lock);
0106 }
0107 
0108 void amdgpu_jpeg_ring_end_use(struct amdgpu_ring *ring)
0109 {
0110     atomic_dec(&ring->adev->jpeg.total_submission_cnt);
0111     schedule_delayed_work(&ring->adev->jpeg.idle_work, JPEG_IDLE_TIMEOUT);
0112 }
0113 
0114 int amdgpu_jpeg_dec_ring_test_ring(struct amdgpu_ring *ring)
0115 {
0116     struct amdgpu_device *adev = ring->adev;
0117     uint32_t tmp = 0;
0118     unsigned i;
0119     int r;
0120 
0121     WREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch, 0xCAFEDEAD);
0122     r = amdgpu_ring_alloc(ring, 3);
0123     if (r)
0124         return r;
0125 
0126     amdgpu_ring_write(ring, PACKET0(adev->jpeg.internal.jpeg_pitch, 0));
0127     amdgpu_ring_write(ring, 0xDEADBEEF);
0128     amdgpu_ring_commit(ring);
0129 
0130     for (i = 0; i < adev->usec_timeout; i++) {
0131         tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
0132         if (tmp == 0xDEADBEEF)
0133             break;
0134         udelay(1);
0135     }
0136 
0137     if (i >= adev->usec_timeout)
0138         r = -ETIMEDOUT;
0139 
0140     return r;
0141 }
0142 
0143 static int amdgpu_jpeg_dec_set_reg(struct amdgpu_ring *ring, uint32_t handle,
0144         struct dma_fence **fence)
0145 {
0146     struct amdgpu_device *adev = ring->adev;
0147     struct amdgpu_job *job;
0148     struct amdgpu_ib *ib;
0149     struct dma_fence *f = NULL;
0150     const unsigned ib_size_dw = 16;
0151     int i, r;
0152 
0153     r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
0154                     AMDGPU_IB_POOL_DIRECT, &job);
0155     if (r)
0156         return r;
0157 
0158     ib = &job->ibs[0];
0159 
0160     ib->ptr[0] = PACKETJ(adev->jpeg.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0);
0161     ib->ptr[1] = 0xDEADBEEF;
0162     for (i = 2; i < 16; i += 2) {
0163         ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
0164         ib->ptr[i+1] = 0;
0165     }
0166     ib->length_dw = 16;
0167 
0168     r = amdgpu_job_submit_direct(job, ring, &f);
0169     if (r)
0170         goto err;
0171 
0172     if (fence)
0173         *fence = dma_fence_get(f);
0174     dma_fence_put(f);
0175 
0176     return 0;
0177 
0178 err:
0179     amdgpu_job_free(job);
0180     return r;
0181 }
0182 
0183 int amdgpu_jpeg_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
0184 {
0185     struct amdgpu_device *adev = ring->adev;
0186     uint32_t tmp = 0;
0187     unsigned i;
0188     struct dma_fence *fence = NULL;
0189     long r = 0;
0190 
0191     r = amdgpu_jpeg_dec_set_reg(ring, 1, &fence);
0192     if (r)
0193         goto error;
0194 
0195     r = dma_fence_wait_timeout(fence, false, timeout);
0196     if (r == 0) {
0197         r = -ETIMEDOUT;
0198         goto error;
0199     } else if (r < 0) {
0200         goto error;
0201     } else {
0202         r = 0;
0203     }
0204 
0205     for (i = 0; i < adev->usec_timeout; i++) {
0206         tmp = RREG32(adev->jpeg.inst[ring->me].external.jpeg_pitch);
0207         if (tmp == 0xDEADBEEF)
0208             break;
0209         udelay(1);
0210     }
0211 
0212     if (i >= adev->usec_timeout)
0213         r = -ETIMEDOUT;
0214 
0215     dma_fence_put(fence);
0216 error:
0217     return r;
0218 }
0219 
0220 int amdgpu_jpeg_process_poison_irq(struct amdgpu_device *adev,
0221                 struct amdgpu_irq_src *source,
0222                 struct amdgpu_iv_entry *entry)
0223 {
0224     struct ras_common_if *ras_if = adev->jpeg.ras_if;
0225     struct ras_dispatch_if ih_data = {
0226         .entry = entry,
0227     };
0228 
0229     if (!ras_if)
0230         return 0;
0231 
0232     ih_data.head = *ras_if;
0233     amdgpu_ras_interrupt_dispatch(adev, &ih_data);
0234 
0235     return 0;
0236 }