Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2013 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.  * Authors: Christian König <christian.koenig@amd.com>
  26.  */
  27.  
  28. #include <linux/firmware.h>
  29. #include <drm/drmP.h>
  30. #include "radeon.h"
  31. #include "radeon_asic.h"
  32. #include "sid.h"
  33.  
  34. /**
  35.  * vce_v1_0_get_rptr - get read pointer
  36.  *
  37.  * @rdev: radeon_device pointer
  38.  * @ring: radeon_ring pointer
  39.  *
  40.  * Returns the current hardware read pointer
  41.  */
  42. uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev,
  43.                            struct radeon_ring *ring)
  44. {
  45.         if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
  46.                 return RREG32(VCE_RB_RPTR);
  47.         else
  48.                 return RREG32(VCE_RB_RPTR2);
  49. }
  50.  
  51. /**
  52.  * vce_v1_0_get_wptr - get write pointer
  53.  *
  54.  * @rdev: radeon_device pointer
  55.  * @ring: radeon_ring pointer
  56.  *
  57.  * Returns the current hardware write pointer
  58.  */
  59. uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev,
  60.                            struct radeon_ring *ring)
  61. {
  62.         if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
  63.                 return RREG32(VCE_RB_WPTR);
  64.         else
  65.                 return RREG32(VCE_RB_WPTR2);
  66. }
  67.  
  68. /**
  69.  * vce_v1_0_set_wptr - set write pointer
  70.  *
  71.  * @rdev: radeon_device pointer
  72.  * @ring: radeon_ring pointer
  73.  *
  74.  * Commits the write pointer to the hardware
  75.  */
  76. void vce_v1_0_set_wptr(struct radeon_device *rdev,
  77.                        struct radeon_ring *ring)
  78. {
  79.         if (ring->idx == TN_RING_TYPE_VCE1_INDEX)
  80.                 WREG32(VCE_RB_WPTR, ring->wptr);
  81.         else
  82.                 WREG32(VCE_RB_WPTR2, ring->wptr);
  83. }
  84.  
  85. /**
  86.  * vce_v1_0_start - start VCE block
  87.  *
  88.  * @rdev: radeon_device pointer
  89.  *
  90.  * Setup and start the VCE block
  91.  */
  92. int vce_v1_0_start(struct radeon_device *rdev)
  93. {
  94.         struct radeon_ring *ring;
  95.         int i, j, r;
  96.  
  97.         /* set BUSY flag */
  98.         WREG32_P(VCE_STATUS, 1, ~1);
  99.  
  100.         ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
  101.         WREG32(VCE_RB_RPTR, ring->wptr);
  102.         WREG32(VCE_RB_WPTR, ring->wptr);
  103.         WREG32(VCE_RB_BASE_LO, ring->gpu_addr);
  104.         WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
  105.         WREG32(VCE_RB_SIZE, ring->ring_size / 4);
  106.  
  107.         ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
  108.         WREG32(VCE_RB_RPTR2, ring->wptr);
  109.         WREG32(VCE_RB_WPTR2, ring->wptr);
  110.         WREG32(VCE_RB_BASE_LO2, ring->gpu_addr);
  111.         WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
  112.         WREG32(VCE_RB_SIZE2, ring->ring_size / 4);
  113.  
  114.         WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN);
  115.  
  116.         WREG32_P(VCE_SOFT_RESET,
  117.                  VCE_ECPU_SOFT_RESET |
  118.                  VCE_FME_SOFT_RESET, ~(
  119.                  VCE_ECPU_SOFT_RESET |
  120.                  VCE_FME_SOFT_RESET));
  121.  
  122.         mdelay(100);
  123.  
  124.         WREG32_P(VCE_SOFT_RESET, 0, ~(
  125.                  VCE_ECPU_SOFT_RESET |
  126.                  VCE_FME_SOFT_RESET));
  127.  
  128.         for (i = 0; i < 10; ++i) {
  129.                 uint32_t status;
  130.                 for (j = 0; j < 100; ++j) {
  131.                         status = RREG32(VCE_STATUS);
  132.                         if (status & 2)
  133.                                 break;
  134.                         mdelay(10);
  135.                 }
  136.                 r = 0;
  137.                 if (status & 2)
  138.                         break;
  139.  
  140.                 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
  141.                 WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET);
  142.                 mdelay(10);
  143.                 WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET);
  144.                 mdelay(10);
  145.                 r = -1;
  146.         }
  147.  
  148.         /* clear BUSY flag */
  149.         WREG32_P(VCE_STATUS, 0, ~1);
  150.  
  151.         if (r) {
  152.                 DRM_ERROR("VCE not responding, giving up!!!\n");
  153.                 return r;
  154.         }
  155.  
  156.         return 0;
  157. }
  158.  
  159. int vce_v1_0_init(struct radeon_device *rdev)
  160. {
  161.         struct radeon_ring *ring;
  162.         int r;
  163.  
  164.         r = vce_v1_0_start(rdev);
  165.         if (r)
  166.                 return r;
  167.  
  168.         ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
  169.         ring->ready = true;
  170.         r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring);
  171.         if (r) {
  172.                 ring->ready = false;
  173.                 return r;
  174.         }
  175.  
  176.         ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
  177.         ring->ready = true;
  178.         r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring);
  179.         if (r) {
  180.                 ring->ready = false;
  181.                 return r;
  182.         }
  183.  
  184.         DRM_INFO("VCE initialized successfully.\n");
  185.  
  186.         return 0;
  187. }
  188.