Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2012 Advanced Micro Devices, Inc.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17.  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20.  * OTHER DEALINGS IN THE SOFTWARE.
  21.  *
  22.  */
  23.  
  24. #include "drmP.h"
  25. #include "radeon.h"
  26. #include "trinityd.h"
  27. #include "trinity_dpm.h"
  28. #include "ppsmc.h"
  29.  
  30. static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
  31. {
  32.         int i;
  33.         u32 v = 0;
  34.  
  35.         WREG32(SMC_MESSAGE_0, id);
  36.         for (i = 0; i < rdev->usec_timeout; i++) {
  37.                 if (RREG32(SMC_RESP_0) != 0)
  38.                         break;
  39.                 udelay(1);
  40.         }
  41.         v = RREG32(SMC_RESP_0);
  42.  
  43.         if (v != 1) {
  44.                 if (v == 0xFF) {
  45.                         DRM_ERROR("SMC failed to handle the message!\n");
  46.                         return -EINVAL;
  47.                 } else if (v == 0xFE) {
  48.                         DRM_ERROR("Unknown SMC message!\n");
  49.                         return -EINVAL;
  50.                 }
  51.         }
  52.  
  53.         return 0;
  54. }
  55.  
  56. int trinity_dpm_bapm_enable(struct radeon_device *rdev, bool enable)
  57. {
  58.         if (enable)
  59.                 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_EnableBAPM);
  60.         else
  61.                 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DisableBAPM);
  62. }
  63.  
  64. int trinity_dpm_config(struct radeon_device *rdev, bool enable)
  65. {
  66.         if (enable)
  67.                 WREG32_SMC(SMU_SCRATCH0, 1);
  68.         else
  69.                 WREG32_SMC(SMU_SCRATCH0, 0);
  70.  
  71.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_Config);
  72. }
  73.  
  74. int trinity_dpm_force_state(struct radeon_device *rdev, u32 n)
  75. {
  76.         WREG32_SMC(SMU_SCRATCH0, n);
  77.  
  78.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_ForceState);
  79. }
  80.  
  81. int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n)
  82. {
  83.         WREG32_SMC(SMU_SCRATCH0, n);
  84.  
  85.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_N_LevelsDisabled);
  86. }
  87.  
  88. int trinity_uvd_dpm_config(struct radeon_device *rdev)
  89. {
  90.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_UVD_DPM_Config);
  91. }
  92.  
  93. int trinity_dpm_no_forced_level(struct radeon_device *rdev)
  94. {
  95.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
  96. }
  97.  
  98. int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev,
  99.                                           bool enable)
  100. {
  101.         if (enable)
  102.                 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_AllowVoltageAdjustment);
  103.         else
  104.                 return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_RemoveVoltageAdjustment);
  105. }
  106.  
  107. int trinity_gfx_dynamic_mgpg_config(struct radeon_device *rdev)
  108. {
  109.         return trinity_notify_message_to_smu(rdev, PPSMC_MSG_PG_SIMD_Config);
  110. }
  111.  
  112. void trinity_acquire_mutex(struct radeon_device *rdev)
  113. {
  114.         int i;
  115.  
  116.         WREG32(SMC_INT_REQ, 1);
  117.         for (i = 0; i < rdev->usec_timeout; i++) {
  118.                 if ((RREG32(SMC_INT_REQ) & 0xffff) == 1)
  119.                         break;
  120.                 udelay(1);
  121.         }
  122. }
  123.  
  124. void trinity_release_mutex(struct radeon_device *rdev)
  125. {
  126.         WREG32(SMC_INT_REQ, 0);
  127. }
  128.