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