aie2_pm.c 2.5 KB

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