cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

trinity_smc.c (3473B)


      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 "radeon.h"
     25#include "trinityd.h"
     26#include "trinity_dpm.h"
     27#include "ppsmc.h"
     28
     29static int trinity_notify_message_to_smu(struct radeon_device *rdev, u32 id)
     30{
     31	int i;
     32	u32 v = 0;
     33
     34	WREG32(SMC_MESSAGE_0, id);
     35	for (i = 0; i < rdev->usec_timeout; i++) {
     36		if (RREG32(SMC_RESP_0) != 0)
     37			break;
     38		udelay(1);
     39	}
     40	v = RREG32(SMC_RESP_0);
     41
     42	if (v != 1) {
     43		if (v == 0xFF) {
     44			DRM_ERROR("SMC failed to handle the message!\n");
     45			return -EINVAL;
     46		} else if (v == 0xFE) {
     47			DRM_ERROR("Unknown SMC message!\n");
     48			return -EINVAL;
     49		}
     50	}
     51
     52	return 0;
     53}
     54
     55int trinity_dpm_bapm_enable(struct radeon_device *rdev, bool enable)
     56{
     57	if (enable)
     58		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_EnableBAPM);
     59	else
     60		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DisableBAPM);
     61}
     62
     63int trinity_dpm_config(struct radeon_device *rdev, bool enable)
     64{
     65	if (enable)
     66		WREG32_SMC(SMU_SCRATCH0, 1);
     67	else
     68		WREG32_SMC(SMU_SCRATCH0, 0);
     69
     70	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_Config);
     71}
     72
     73int trinity_dpm_force_state(struct radeon_device *rdev, u32 n)
     74{
     75	WREG32_SMC(SMU_SCRATCH0, n);
     76
     77	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_ForceState);
     78}
     79
     80int trinity_dpm_n_levels_disabled(struct radeon_device *rdev, u32 n)
     81{
     82	WREG32_SMC(SMU_SCRATCH0, n);
     83
     84	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DPM_N_LevelsDisabled);
     85}
     86
     87int trinity_uvd_dpm_config(struct radeon_device *rdev)
     88{
     89	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_UVD_DPM_Config);
     90}
     91
     92int trinity_dpm_no_forced_level(struct radeon_device *rdev)
     93{
     94	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
     95}
     96
     97int trinity_dce_enable_voltage_adjustment(struct radeon_device *rdev,
     98					  bool enable)
     99{
    100	if (enable)
    101		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_AllowVoltageAdjustment);
    102	else
    103		return trinity_notify_message_to_smu(rdev, PPSMC_MSG_DCE_RemoveVoltageAdjustment);
    104}
    105
    106int trinity_gfx_dynamic_mgpg_config(struct radeon_device *rdev)
    107{
    108	return trinity_notify_message_to_smu(rdev, PPSMC_MSG_PG_SIMD_Config);
    109}
    110
    111void trinity_acquire_mutex(struct radeon_device *rdev)
    112{
    113	int i;
    114
    115	WREG32(SMC_INT_REQ, 1);
    116	for (i = 0; i < rdev->usec_timeout; i++) {
    117		if ((RREG32(SMC_INT_REQ) & 0xffff) == 1)
    118			break;
    119		udelay(1);
    120	}
    121}
    122
    123void trinity_release_mutex(struct radeon_device *rdev)
    124{
    125	WREG32(SMC_INT_REQ, 0);
    126}