linux/drivers/gpu/drm/amd/amdgpu/fiji_dpm.c
<<
>>
Prefs
   1/*
   2 * Copyright 2014 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 <linux/firmware.h>
  25#include "drmP.h"
  26#include "amdgpu.h"
  27#include "fiji_smum.h"
  28
  29MODULE_FIRMWARE("amdgpu/fiji_smc.bin");
  30
  31static void fiji_dpm_set_funcs(struct amdgpu_device *adev);
  32
  33static int fiji_dpm_early_init(void *handle)
  34{
  35        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  36
  37        fiji_dpm_set_funcs(adev);
  38
  39        return 0;
  40}
  41
  42static int fiji_dpm_init_microcode(struct amdgpu_device *adev)
  43{
  44        char fw_name[30] = "amdgpu/fiji_smc.bin";
  45        int err;
  46
  47        err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
  48        if (err)
  49                goto out;
  50        err = amdgpu_ucode_validate(adev->pm.fw);
  51
  52out:
  53        if (err) {
  54                DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
  55                release_firmware(adev->pm.fw);
  56                adev->pm.fw = NULL;
  57        }
  58        return err;
  59}
  60
  61static int fiji_dpm_sw_init(void *handle)
  62{
  63        int ret;
  64        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  65
  66        ret = fiji_dpm_init_microcode(adev);
  67        if (ret)
  68                return ret;
  69
  70        return 0;
  71}
  72
  73static int fiji_dpm_sw_fini(void *handle)
  74{
  75        return 0;
  76}
  77
  78static int fiji_dpm_hw_init(void *handle)
  79{
  80        int ret;
  81        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
  82
  83        mutex_lock(&adev->pm.mutex);
  84
  85        ret = fiji_smu_init(adev);
  86        if (ret) {
  87                DRM_ERROR("SMU initialization failed\n");
  88                goto fail;
  89        }
  90
  91        ret = fiji_smu_start(adev);
  92        if (ret) {
  93                DRM_ERROR("SMU start failed\n");
  94                goto fail;
  95        }
  96
  97        mutex_unlock(&adev->pm.mutex);
  98        return 0;
  99
 100fail:
 101        adev->firmware.smu_load = false;
 102        mutex_unlock(&adev->pm.mutex);
 103        return -EINVAL;
 104}
 105
 106static int fiji_dpm_hw_fini(void *handle)
 107{
 108        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 109        mutex_lock(&adev->pm.mutex);
 110        fiji_smu_fini(adev);
 111        mutex_unlock(&adev->pm.mutex);
 112        return 0;
 113}
 114
 115static int fiji_dpm_suspend(void *handle)
 116{
 117        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 118
 119        fiji_dpm_hw_fini(adev);
 120
 121        return 0;
 122}
 123
 124static int fiji_dpm_resume(void *handle)
 125{
 126        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 127
 128        fiji_dpm_hw_init(adev);
 129
 130        return 0;
 131}
 132
 133static int fiji_dpm_set_clockgating_state(void *handle,
 134                        enum amd_clockgating_state state)
 135{
 136        return 0;
 137}
 138
 139static int fiji_dpm_set_powergating_state(void *handle,
 140                        enum amd_powergating_state state)
 141{
 142        return 0;
 143}
 144
 145const struct amd_ip_funcs fiji_dpm_ip_funcs = {
 146        .early_init = fiji_dpm_early_init,
 147        .late_init = NULL,
 148        .sw_init = fiji_dpm_sw_init,
 149        .sw_fini = fiji_dpm_sw_fini,
 150        .hw_init = fiji_dpm_hw_init,
 151        .hw_fini = fiji_dpm_hw_fini,
 152        .suspend = fiji_dpm_suspend,
 153        .resume = fiji_dpm_resume,
 154        .is_idle = NULL,
 155        .wait_for_idle = NULL,
 156        .soft_reset = NULL,
 157        .print_status = NULL,
 158        .set_clockgating_state = fiji_dpm_set_clockgating_state,
 159        .set_powergating_state = fiji_dpm_set_powergating_state,
 160};
 161
 162static const struct amdgpu_dpm_funcs fiji_dpm_funcs = {
 163        .get_temperature = NULL,
 164        .pre_set_power_state = NULL,
 165        .set_power_state = NULL,
 166        .post_set_power_state = NULL,
 167        .display_configuration_changed = NULL,
 168        .get_sclk = NULL,
 169        .get_mclk = NULL,
 170        .print_power_state = NULL,
 171        .debugfs_print_current_performance_level = NULL,
 172        .force_performance_level = NULL,
 173        .vblank_too_short = NULL,
 174        .powergate_uvd = NULL,
 175};
 176
 177static void fiji_dpm_set_funcs(struct amdgpu_device *adev)
 178{
 179        if (NULL == adev->pm.funcs)
 180                adev->pm.funcs = &fiji_dpm_funcs;
 181}
 182