Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2013 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Christian König <christian.koenig@amd.com>
0023  */
0024 
0025 #include <linux/firmware.h>
0026 
0027 #include "radeon.h"
0028 #include "radeon_asic.h"
0029 #include "r600d.h"
0030 
0031 /**
0032  * uvd_v1_0_get_rptr - get read pointer
0033  *
0034  * @rdev: radeon_device pointer
0035  * @ring: radeon_ring pointer
0036  *
0037  * Returns the current hardware read pointer
0038  */
0039 uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
0040                struct radeon_ring *ring)
0041 {
0042     return RREG32(UVD_RBC_RB_RPTR);
0043 }
0044 
0045 /**
0046  * uvd_v1_0_get_wptr - get write pointer
0047  *
0048  * @rdev: radeon_device pointer
0049  * @ring: radeon_ring pointer
0050  *
0051  * Returns the current hardware write pointer
0052  */
0053 uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
0054                struct radeon_ring *ring)
0055 {
0056     return RREG32(UVD_RBC_RB_WPTR);
0057 }
0058 
0059 /**
0060  * uvd_v1_0_set_wptr - set write pointer
0061  *
0062  * @rdev: radeon_device pointer
0063  * @ring: radeon_ring pointer
0064  *
0065  * Commits the write pointer to the hardware
0066  */
0067 void uvd_v1_0_set_wptr(struct radeon_device *rdev,
0068                struct radeon_ring *ring)
0069 {
0070     WREG32(UVD_RBC_RB_WPTR, ring->wptr);
0071 }
0072 
0073 /**
0074  * uvd_v1_0_fence_emit - emit an fence & trap command
0075  *
0076  * @rdev: radeon_device pointer
0077  * @fence: fence to emit
0078  *
0079  * Write a fence and a trap command to the ring.
0080  */
0081 void uvd_v1_0_fence_emit(struct radeon_device *rdev,
0082              struct radeon_fence *fence)
0083 {
0084     struct radeon_ring *ring = &rdev->ring[fence->ring];
0085     uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
0086 
0087     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
0088     radeon_ring_write(ring, addr & 0xffffffff);
0089     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
0090     radeon_ring_write(ring, fence->seq);
0091     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
0092     radeon_ring_write(ring, 0);
0093 
0094     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
0095     radeon_ring_write(ring, 0);
0096     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
0097     radeon_ring_write(ring, 0);
0098     radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
0099     radeon_ring_write(ring, 2);
0100     return;
0101 }
0102 
0103 /**
0104  * uvd_v1_0_resume - memory controller programming
0105  *
0106  * @rdev: radeon_device pointer
0107  *
0108  * Let the UVD memory controller know it's offsets
0109  */
0110 int uvd_v1_0_resume(struct radeon_device *rdev)
0111 {
0112     uint64_t addr;
0113     uint32_t size;
0114     int r;
0115 
0116     r = radeon_uvd_resume(rdev);
0117     if (r)
0118         return r;
0119 
0120     /* program the VCPU memory controller bits 0-27 */
0121     addr = (rdev->uvd.gpu_addr >> 3) + 16;
0122     size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
0123     WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
0124     WREG32(UVD_VCPU_CACHE_SIZE0, size);
0125 
0126     addr += size;
0127     size = RADEON_UVD_HEAP_SIZE >> 3;
0128     WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
0129     WREG32(UVD_VCPU_CACHE_SIZE1, size);
0130 
0131     addr += size;
0132     size = (RADEON_UVD_STACK_SIZE +
0133            (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3;
0134     WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
0135     WREG32(UVD_VCPU_CACHE_SIZE2, size);
0136 
0137     /* bits 28-31 */
0138     addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
0139     WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));
0140 
0141     /* bits 32-39 */
0142     addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
0143     WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));
0144 
0145     WREG32(UVD_FW_START, *((uint32_t*)rdev->uvd.cpu_addr));
0146 
0147     return 0;
0148 }
0149 
0150 /**
0151  * uvd_v1_0_init - start and test UVD block
0152  *
0153  * @rdev: radeon_device pointer
0154  *
0155  * Initialize the hardware, boot up the VCPU and do some testing
0156  */
0157 int uvd_v1_0_init(struct radeon_device *rdev)
0158 {
0159     struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
0160     uint32_t tmp;
0161     int r;
0162 
0163     /* raise clocks while booting up the VCPU */
0164     if (rdev->family < CHIP_RV740)
0165         radeon_set_uvd_clocks(rdev, 10000, 10000);
0166     else
0167         radeon_set_uvd_clocks(rdev, 53300, 40000);
0168 
0169     r = uvd_v1_0_start(rdev);
0170     if (r)
0171         goto done;
0172 
0173     ring->ready = true;
0174     r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
0175     if (r) {
0176         ring->ready = false;
0177         goto done;
0178     }
0179 
0180     r = radeon_ring_lock(rdev, ring, 10);
0181     if (r) {
0182         DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
0183         goto done;
0184     }
0185 
0186     tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
0187     radeon_ring_write(ring, tmp);
0188     radeon_ring_write(ring, 0xFFFFF);
0189 
0190     tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
0191     radeon_ring_write(ring, tmp);
0192     radeon_ring_write(ring, 0xFFFFF);
0193 
0194     tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
0195     radeon_ring_write(ring, tmp);
0196     radeon_ring_write(ring, 0xFFFFF);
0197 
0198     /* Clear timeout status bits */
0199     radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
0200     radeon_ring_write(ring, 0x8);
0201 
0202     radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
0203     radeon_ring_write(ring, 3);
0204 
0205     radeon_ring_unlock_commit(rdev, ring, false);
0206 
0207 done:
0208     /* lower clocks again */
0209     radeon_set_uvd_clocks(rdev, 0, 0);
0210 
0211     if (!r) {
0212         switch (rdev->family) {
0213         case CHIP_RV610:
0214         case CHIP_RV630:
0215         case CHIP_RV620:
0216             /* 64byte granularity workaround */
0217             WREG32(MC_CONFIG, 0);
0218             WREG32(MC_CONFIG, 1 << 4);
0219             WREG32(RS_DQ_RD_RET_CONF, 0x3f);
0220             WREG32(MC_CONFIG, 0x1f);
0221 
0222             fallthrough;
0223         case CHIP_RV670:
0224         case CHIP_RV635:
0225 
0226             /* write clean workaround */
0227             WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
0228             break;
0229 
0230         default:
0231             /* TODO: Do we need more? */
0232             break;
0233         }
0234 
0235         DRM_INFO("UVD initialized successfully.\n");
0236     }
0237 
0238     return r;
0239 }
0240 
0241 /**
0242  * uvd_v1_0_fini - stop the hardware block
0243  *
0244  * @rdev: radeon_device pointer
0245  *
0246  * Stop the UVD block, mark ring as not ready any more
0247  */
0248 void uvd_v1_0_fini(struct radeon_device *rdev)
0249 {
0250     struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
0251 
0252     uvd_v1_0_stop(rdev);
0253     ring->ready = false;
0254 }
0255 
0256 /**
0257  * uvd_v1_0_start - start UVD block
0258  *
0259  * @rdev: radeon_device pointer
0260  *
0261  * Setup and start the UVD block
0262  */
0263 int uvd_v1_0_start(struct radeon_device *rdev)
0264 {
0265     struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
0266     uint32_t rb_bufsz;
0267     int i, j, r;
0268 
0269     /* disable byte swapping */
0270     u32 lmi_swap_cntl = 0;
0271     u32 mp_swap_cntl = 0;
0272 
0273     /* disable clock gating */
0274     WREG32(UVD_CGC_GATE, 0);
0275 
0276     /* disable interupt */
0277     WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));
0278 
0279     /* Stall UMC and register bus before resetting VCPU */
0280     WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
0281     WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
0282     mdelay(1);
0283 
0284     /* put LMI, VCPU, RBC etc... into reset */
0285     WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
0286            LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
0287            CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
0288     mdelay(5);
0289 
0290     /* take UVD block out of reset */
0291     WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
0292     mdelay(5);
0293 
0294     /* initialize UVD memory controller */
0295     WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
0296                  (1 << 21) | (1 << 9) | (1 << 20));
0297 
0298 #ifdef __BIG_ENDIAN
0299     /* swap (8 in 32) RB and IB */
0300     lmi_swap_cntl = 0xa;
0301     mp_swap_cntl = 0;
0302 #endif
0303     WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
0304     WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);
0305 
0306     WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
0307     WREG32(UVD_MPC_SET_MUXA1, 0x0);
0308     WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
0309     WREG32(UVD_MPC_SET_MUXB1, 0x0);
0310     WREG32(UVD_MPC_SET_ALU, 0);
0311     WREG32(UVD_MPC_SET_MUX, 0x88);
0312 
0313     /* take all subblocks out of reset, except VCPU */
0314     WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
0315     mdelay(5);
0316 
0317     /* enable VCPU clock */
0318     WREG32(UVD_VCPU_CNTL,  1 << 9);
0319 
0320     /* enable UMC */
0321     WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
0322 
0323     WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
0324 
0325     /* boot up the VCPU */
0326     WREG32(UVD_SOFT_RESET, 0);
0327     mdelay(10);
0328 
0329     for (i = 0; i < 10; ++i) {
0330         uint32_t status;
0331         for (j = 0; j < 100; ++j) {
0332             status = RREG32(UVD_STATUS);
0333             if (status & 2)
0334                 break;
0335             mdelay(10);
0336         }
0337         r = 0;
0338         if (status & 2)
0339             break;
0340 
0341         DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
0342         WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
0343         mdelay(10);
0344         WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
0345         mdelay(10);
0346         r = -1;
0347     }
0348 
0349     if (r) {
0350         DRM_ERROR("UVD not responding, giving up!!!\n");
0351         return r;
0352     }
0353 
0354     /* enable interupt */
0355     WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));
0356 
0357     /* force RBC into idle state */
0358     WREG32(UVD_RBC_RB_CNTL, 0x11010101);
0359 
0360     /* Set the write pointer delay */
0361     WREG32(UVD_RBC_RB_WPTR_CNTL, 0);
0362 
0363     /* program the 4GB memory segment for rptr and ring buffer */
0364     WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
0365                    (0x7 << 16) | (0x1 << 31));
0366 
0367     /* Initialize the ring buffer's read and write pointers */
0368     WREG32(UVD_RBC_RB_RPTR, 0x0);
0369 
0370     ring->wptr = RREG32(UVD_RBC_RB_RPTR);
0371     WREG32(UVD_RBC_RB_WPTR, ring->wptr);
0372 
0373     /* set the ring address */
0374     WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);
0375 
0376     /* Set ring buffer size */
0377     rb_bufsz = order_base_2(ring->ring_size);
0378     rb_bufsz = (0x1 << 8) | rb_bufsz;
0379     WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);
0380 
0381     return 0;
0382 }
0383 
0384 /**
0385  * uvd_v1_0_stop - stop UVD block
0386  *
0387  * @rdev: radeon_device pointer
0388  *
0389  * stop the UVD block
0390  */
0391 void uvd_v1_0_stop(struct radeon_device *rdev)
0392 {
0393     /* force RBC into idle state */
0394     WREG32(UVD_RBC_RB_CNTL, 0x11010101);
0395 
0396     /* Stall UMC and register bus before resetting VCPU */
0397     WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
0398     WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
0399     mdelay(1);
0400 
0401     /* put VCPU into reset */
0402     WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
0403     mdelay(5);
0404 
0405     /* disable VCPU clock */
0406     WREG32(UVD_VCPU_CNTL, 0x0);
0407 
0408     /* Unstall UMC and register bus */
0409     WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
0410     WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
0411 }
0412 
0413 /**
0414  * uvd_v1_0_ring_test - register write test
0415  *
0416  * @rdev: radeon_device pointer
0417  * @ring: radeon_ring pointer
0418  *
0419  * Test if we can successfully write to the context register
0420  */
0421 int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
0422 {
0423     uint32_t tmp = 0;
0424     unsigned i;
0425     int r;
0426 
0427     WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
0428     r = radeon_ring_lock(rdev, ring, 3);
0429     if (r) {
0430         DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
0431               ring->idx, r);
0432         return r;
0433     }
0434     radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
0435     radeon_ring_write(ring, 0xDEADBEEF);
0436     radeon_ring_unlock_commit(rdev, ring, false);
0437     for (i = 0; i < rdev->usec_timeout; i++) {
0438         tmp = RREG32(UVD_CONTEXT_ID);
0439         if (tmp == 0xDEADBEEF)
0440             break;
0441         udelay(1);
0442     }
0443 
0444     if (i < rdev->usec_timeout) {
0445         DRM_INFO("ring test on %d succeeded in %d usecs\n",
0446              ring->idx, i);
0447     } else {
0448         DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
0449               ring->idx, tmp);
0450         r = -EINVAL;
0451     }
0452     return r;
0453 }
0454 
0455 /**
0456  * uvd_v1_0_semaphore_emit - emit semaphore command
0457  *
0458  * @rdev: radeon_device pointer
0459  * @ring: radeon_ring pointer
0460  * @semaphore: semaphore to emit commands for
0461  * @emit_wait: true if we should emit a wait command
0462  *
0463  * Emit a semaphore command (either wait or signal) to the UVD ring.
0464  */
0465 bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
0466                  struct radeon_ring *ring,
0467                  struct radeon_semaphore *semaphore,
0468                  bool emit_wait)
0469 {
0470     /* disable semaphores for UVD V1 hardware */
0471     return false;
0472 }
0473 
0474 /**
0475  * uvd_v1_0_ib_execute - execute indirect buffer
0476  *
0477  * @rdev: radeon_device pointer
0478  * @ib: indirect buffer to execute
0479  *
0480  * Write ring commands to execute the indirect buffer
0481  */
0482 void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
0483 {
0484     struct radeon_ring *ring = &rdev->ring[ib->ring];
0485 
0486     radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
0487     radeon_ring_write(ring, ib->gpu_addr);
0488     radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
0489     radeon_ring_write(ring, ib->length_dw);
0490 }
0491 
0492 /**
0493  * uvd_v1_0_ib_test - test ib execution
0494  *
0495  * @rdev: radeon_device pointer
0496  * @ring: radeon_ring pointer
0497  *
0498  * Test if we can successfully execute an IB
0499  */
0500 int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
0501 {
0502     struct radeon_fence *fence = NULL;
0503     int r;
0504 
0505     if (rdev->family < CHIP_RV740)
0506         r = radeon_set_uvd_clocks(rdev, 10000, 10000);
0507     else
0508         r = radeon_set_uvd_clocks(rdev, 53300, 40000);
0509     if (r) {
0510         DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
0511         return r;
0512     }
0513 
0514     r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
0515     if (r) {
0516         DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
0517         goto error;
0518     }
0519 
0520     r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
0521     if (r) {
0522         DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
0523         goto error;
0524     }
0525 
0526     r = radeon_fence_wait_timeout(fence, false, usecs_to_jiffies(
0527         RADEON_USEC_IB_TEST_TIMEOUT));
0528     if (r < 0) {
0529         DRM_ERROR("radeon: fence wait failed (%d).\n", r);
0530         goto error;
0531     } else if (r == 0) {
0532         DRM_ERROR("radeon: fence wait timed out.\n");
0533         r = -ETIMEDOUT;
0534         goto error;
0535     }
0536     r = 0;
0537     DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
0538 error:
0539     radeon_fence_unref(&fence);
0540     radeon_set_uvd_clocks(rdev, 0, 0);
0541     return r;
0542 }