1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2024, Advanced Micro Devices, Inc. 4 */ 5 6 #include <drm/amdxdna_accel.h> 7 #include <drm/drm_device.h> 8 #include <drm/drm_print.h> 9 #include <drm/gpu_scheduler.h> 10 11 #include "aie2_pci.h" 12 #include "amdxdna_pci_drv.h" 13 14 #define AIE2_CLK_GATING_ENABLE 1 15 #define AIE2_CLK_GATING_DISABLE 0 16 17 static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val) 18 { 19 int ret; 20 21 ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, &val); 22 if (ret) 23 return ret; 24 25 ndev->clk_gating = val; 26 return 0; 27 } 28 29 int aie2_pm_init(struct amdxdna_dev_hdl *ndev) 30 { 31 int ret; 32 33 if (ndev->dev_status != AIE2_DEV_UNINIT) { 34 /* Resume device */ 35 ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->dpm_level); 36 if (ret) 37 return ret; 38 39 ret = aie2_pm_set_clk_gating(ndev, ndev->clk_gating); 40 if (ret) 41 return ret; 42 43 return 0; 44 } 45 46 while (ndev->priv->dpm_clk_tbl[ndev->max_dpm_level].hclk) 47 ndev->max_dpm_level++; 48 ndev->max_dpm_level--; 49 50 ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->max_dpm_level); 51 if (ret) 52 return ret; 53 54 ret = aie2_pm_set_clk_gating(ndev, AIE2_CLK_GATING_ENABLE); 55 if (ret) 56 return ret; 57 58 ndev->pw_mode = POWER_MODE_DEFAULT; 59 ndev->dft_dpm_level = ndev->max_dpm_level; 60 61 return 0; 62 } 63 64 int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type target) 65 { 66 struct amdxdna_dev *xdna = ndev->xdna; 67 u32 clk_gating, dpm_level; 68 int ret; 69 70 drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); 71 72 if (ndev->pw_mode == target) 73 return 0; 74 75 switch (target) { 76 case POWER_MODE_TURBO: 77 if (ndev->hwctx_num) { 78 XDNA_ERR(xdna, "Can not set turbo when there is active hwctx"); 79 return -EINVAL; 80 } 81 82 clk_gating = AIE2_CLK_GATING_DISABLE; 83 dpm_level = ndev->max_dpm_level; 84 break; 85 case POWER_MODE_HIGH: 86 clk_gating = AIE2_CLK_GATING_ENABLE; 87 dpm_level = ndev->max_dpm_level; 88 break; 89 case POWER_MODE_DEFAULT: 90 clk_gating = AIE2_CLK_GATING_ENABLE; 91 dpm_level = ndev->dft_dpm_level; 92 break; 93 default: 94 return -EOPNOTSUPP; 95 } 96 97 ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level); 98 if (ret) 99 return ret; 100 101 ret = aie2_pm_set_clk_gating(ndev, clk_gating); 102 if (ret) 103 return ret; 104 105 ndev->pw_mode = target; 106 107 return 0; 108 } 109