| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Copyright (C) 2024, Advanced Micro Devices, Inc.
- */
- #include <drm/amdxdna_accel.h>
- #include <drm/drm_device.h>
- #include <drm/drm_print.h>
- #include <drm/gpu_scheduler.h>
- #include "aie2_pci.h"
- #include "amdxdna_pci_drv.h"
- #include "amdxdna_pm.h"
- #define AIE2_CLK_GATING_ENABLE 1
- #define AIE2_CLK_GATING_DISABLE 0
- static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val)
- {
- int ret;
- ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, &val);
- if (ret)
- return ret;
- ndev->clk_gating = val;
- return 0;
- }
- int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
- {
- int ret;
- ret = amdxdna_pm_resume_get_locked(ndev->xdna);
- if (ret)
- return ret;
- ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
- if (!ret)
- ndev->dpm_level = dpm_level;
- amdxdna_pm_suspend_put(ndev->xdna);
- return ret;
- }
- int aie2_pm_init(struct amdxdna_dev_hdl *ndev)
- {
- int ret;
- if (ndev->dev_status != AIE2_DEV_UNINIT) {
- /* Resume device */
- ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->dpm_level);
- if (ret)
- return ret;
- ret = aie2_pm_set_clk_gating(ndev, ndev->clk_gating);
- if (ret)
- return ret;
- return 0;
- }
- while (ndev->priv->dpm_clk_tbl[ndev->max_dpm_level].hclk)
- ndev->max_dpm_level++;
- ndev->max_dpm_level--;
- ret = ndev->priv->hw_ops.set_dpm(ndev, ndev->max_dpm_level);
- if (ret)
- return ret;
- ndev->dpm_level = ndev->max_dpm_level;
- ret = aie2_pm_set_clk_gating(ndev, AIE2_CLK_GATING_ENABLE);
- if (ret)
- return ret;
- ndev->pw_mode = POWER_MODE_DEFAULT;
- ndev->dft_dpm_level = ndev->max_dpm_level;
- return 0;
- }
- int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type target)
- {
- struct amdxdna_dev *xdna = ndev->xdna;
- u32 clk_gating, dpm_level;
- int ret;
- drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
- if (ndev->pw_mode == target)
- return 0;
- switch (target) {
- case POWER_MODE_TURBO:
- if (ndev->hwctx_num) {
- XDNA_ERR(xdna, "Can not set turbo when there is active hwctx");
- return -EINVAL;
- }
- clk_gating = AIE2_CLK_GATING_DISABLE;
- dpm_level = ndev->max_dpm_level;
- break;
- case POWER_MODE_HIGH:
- clk_gating = AIE2_CLK_GATING_ENABLE;
- dpm_level = ndev->max_dpm_level;
- break;
- case POWER_MODE_DEFAULT:
- clk_gating = AIE2_CLK_GATING_ENABLE;
- dpm_level = ndev->dft_dpm_level;
- break;
- default:
- return -EOPNOTSUPP;
- }
- ret = aie2_pm_set_dpm(ndev, dpm_level);
- if (ret)
- return ret;
- ret = aie2_pm_set_clk_gating(ndev, clk_gating);
- if (ret)
- return ret;
- ndev->pw_mode = target;
- return 0;
- }
|