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 #include "amdxdna_pm.h" 14 15 #define AIE2_CLK_GATING_ENABLE 1 16 #define AIE2_CLK_GATING_DISABLE 0 17 18 static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val) 19 { 20 int ret; 21 22 ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, &val); 23 if (ret) 24 return ret; 25 26 ndev->clk_gating = val; 27 return 0; 28 } 29 30 int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) 31 { 32 int ret; 33 34 ret = amdxdna_pm_resume_get(ndev->xdna); 35 if (ret) 36 return ret; 37 38 ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level); 39 amdxdna_pm_suspend_put(ndev->xdna); 40 41 return ret; 42 } 43 44 int aie2_pm_init(struct amdxdna_dev_hdl *ndev) 45 { 46 int ret; 47 48 if (ndev->dev_status != AIE2_DEV_UNINIT) { 49 /* Resume device */ 50 ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->dpm_level); 51 if (ret) 52 return ret; 53 54 ret = aie2_pm_set_clk_gating(ndev, ndev->clk_gating); 55 if (ret) 56 return ret; 57 58 return 0; 59 } 60 61 while (ndev->priv->dpm_clk_tbl[ndev->max_dpm_level].hclk) 62 ndev->max_dpm_level++; 63 ndev->max_dpm_level--; 64 65 ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->max_dpm_level); 66 if (ret) 67 return ret; 68 69 ret = aie2_pm_set_clk_gating(ndev, AIE2_CLK_GATING_ENABLE); 70 if (ret) 71 return ret; 72 73 ndev->pw_mode = POWER_MODE_DEFAULT; 74 ndev->dft_dpm_level = ndev->max_dpm_level; 75 76 return 0; 77 } 78 79 int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type target) 80 { 81 struct amdxdna_dev *xdna = ndev->xdna; 82 u32 clk_gating, dpm_level; 83 int ret; 84 85 drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); 86 87 if (ndev->pw_mode == target) 88 return 0; 89 90 switch (target) { 91 case POWER_MODE_TURBO: 92 if (ndev->hwctx_num) { 93 XDNA_ERR(xdna, "Can not set turbo when there is active hwctx"); 94 return -EINVAL; 95 } 96 97 clk_gating = AIE2_CLK_GATING_DISABLE; 98 dpm_level = ndev->max_dpm_level; 99 break; 100 case POWER_MODE_HIGH: 101 clk_gating = AIE2_CLK_GATING_ENABLE; 102 dpm_level = ndev->max_dpm_level; 103 break; 104 case POWER_MODE_DEFAULT: 105 clk_gating = AIE2_CLK_GATING_ENABLE; 106 dpm_level = ndev->dft_dpm_level; 107 break; 108 default: 109 return -EOPNOTSUPP; 110 } 111 112 ret = aie2_pm_set_dpm(ndev, dpm_level); 113 if (ret) 114 return ret; 115 116 ret = aie2_pm_set_clk_gating(ndev, clk_gating); 117 if (ret) 118 return ret; 119 120 ndev->pw_mode = target; 121 122 return 0; 123 } 124