Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor power management #313

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/driver/amdxdna/aie2_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
struct drm_gpu_scheduler *sched;
struct amdxdna_hwctx_priv *priv;
struct amdxdna_gem_obj *heap;
struct amdxdna_dev_hdl *ndev;
unsigned int wq_flags;
int i, ret;

Expand Down Expand Up @@ -722,6 +723,8 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
goto release_resource;
}
hwctx->status = HWCTX_STATE_INIT;
ndev = xdna->dev_handle;
ndev->hwctx_num++;

XDNA_DBG(xdna, "hwctx %s init completed", hwctx->name);

Expand Down Expand Up @@ -753,10 +756,13 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)

void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx)
{
struct amdxdna_dev_hdl *ndev;
struct amdxdna_dev *xdna;
int idx;

xdna = hwctx->client->xdna;
ndev = xdna->dev_handle;
ndev->hwctx_num--;
drm_sched_wqueue_stop(&hwctx->priv->sched);

/* Now, scheduler will not send command to device. */
Expand Down
15 changes: 8 additions & 7 deletions src/driver/amdxdna/aie2_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,10 @@ static ssize_t aie2_dpm_level_set(struct file *file, const char __user *ptr,
}

mutex_lock(&ndev->xdna->dev_lock);
ret = aie2_smu_set_fixed_dpm_level(ndev, val);
ndev->dft_dpm_level = val;
if (ndev->pw_mode != POWER_MODE_DEFAULT)
val = ndev->dpm_level;
ret = ndev->priv->hw_ops.set_dpm(ndev, val);
mutex_unlock(&ndev->xdna->dev_lock);
if (ret) {
XDNA_ERR(ndev->xdna, "Setting dpm_level:%d failed, ret: %d", val, ret);
Expand All @@ -239,15 +242,13 @@ static ssize_t aie2_dpm_level_set(struct file *file, const char __user *ptr,
static int aie2_dpm_level_get(struct seq_file *m, void *unused)
{
struct amdxdna_dev_hdl *ndev = m->private;
const struct dpm_clk *dpm_table;
u32 num_dpm_levels;
const struct dpm_clk_freq *dpm_table;
int dpm_level;
int i;

dpm_table = SMU_DPM_TABLE_ENTRY(ndev, 0);
dpm_level = aie2_smu_get_dpm_level(ndev);
num_dpm_levels = SMU_DPM_MAX(ndev);
for (i = 0; i <= num_dpm_levels; i++) {
dpm_table = ndev->priv->dpm_clk_tbl;
dpm_level = ndev->dpm_level;
for (i = 0; dpm_table[i].hclk; i++) {
u32 npuclk = dpm_table[i].npuclk;
u32 hclk = dpm_table[i].hclk;

Expand Down
9 changes: 8 additions & 1 deletion src/driver/amdxdna/aie2_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,18 @@ int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value)
{
DECLARE_AIE2_MSG(set_runtime_cfg, MSG_OP_SET_RUNTIME_CONFIG);
int ret;

req.type = type;
req.value = value;

return aie2_send_mgmt_msg_wait(ndev, &msg);
ret = aie2_send_mgmt_msg_wait(ndev, &msg);
if (ret) {
XDNA_ERR(ndev->xdna, "Failed to set runtime config, ret %d", ret);
return ret;
}

return 0;
}

int aie2_get_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 *value)
Expand Down
95 changes: 56 additions & 39 deletions src/driver/amdxdna/aie2_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,37 +177,32 @@ static int aie2_get_mgmt_chann_info(struct amdxdna_dev_hdl *ndev)
return ret;
}

static int aie2_runtime_cfg(struct amdxdna_dev_hdl *ndev)
int aie2_runtime_cfg(struct amdxdna_dev_hdl *ndev,
enum rt_config_category category, u32 *val)
{
int i;
const struct rt_config *cfg;
u32 value;
int ret;

for (i = 0; i < ndev->priv->num_rt_cfg; i++) {
const struct rt_config *cfg = &ndev->priv->rt_config[i];
u64 value;
int ret;
for (cfg = ndev->priv->rt_config; cfg->type; cfg++) {
if (cfg->category != category)
continue;

value = val ? *val : cfg->value;
#ifdef AMDXDNA_DEVEL
if (priv_load && cfg->type == ndev->priv->priv_load_cfg.type) {
cfg = &ndev->priv->priv_load_cfg;
value = cfg->value;
XDNA_INFO(ndev->xdna, "Set runtime type %d value %d",
cfg->type, cfg->value);
}
#endif
ret = aie2_set_runtime_cfg(ndev, cfg->type, cfg->value);
ret = aie2_set_runtime_cfg(ndev, cfg->type, value);
if (ret) {
XDNA_ERR(ndev->xdna, "Set runtime type %d value %d failed",
cfg->type, cfg->value);
return ret;
}

ret = aie2_get_runtime_cfg(ndev, cfg->type, &value);
if (ret) {
XDNA_ERR(ndev->xdna, "Get runtime cfg failed");
cfg->type, value);
return ret;
}

if (value != cfg->value)
return -EINVAL;
}

return 0;
Expand Down Expand Up @@ -244,7 +239,7 @@ static int aie2_mgmt_fw_init(struct amdxdna_dev_hdl *ndev)
}
}

ret = aie2_runtime_cfg(ndev);
ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_INIT, NULL);
if (ret) {
XDNA_ERR(ndev->xdna, "Runtime config failed");
return ret;
Expand Down Expand Up @@ -306,18 +301,37 @@ static void aie2_mgmt_fw_fini(struct amdxdna_dev_hdl *ndev)
XDNA_DBG(ndev->xdna, "npu firmware suspended");
}

static int aie2_xrs_set_dft_dpm_level(struct drm_device *ddev, u32 dpm_level)
{
struct amdxdna_dev *xdna = to_xdna_dev(ddev);
struct amdxdna_dev_hdl *ndev;

drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));

ndev = xdna->dev_handle;
ndev->dft_dpm_level = dpm_level;
if (ndev->pw_mode != POWER_MODE_DEFAULT || ndev->dpm_level == dpm_level)
return 0;

return ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
}

static struct xrs_action_ops aie2_xrs_actions = {
.load_hwctx = aie2_xrs_load_hwctx,
.unload_hwctx = aie2_xrs_unload_hwctx,
.set_dpm_level = aie2_smu_set_dft_dpm_level,
.set_dft_dpm_level = aie2_xrs_set_dft_dpm_level,
};

static void aie2_hw_stop(struct amdxdna_dev *xdna)
{
struct pci_dev *pdev = to_pci_dev(xdna->ddev.dev);
struct amdxdna_dev_hdl *ndev = xdna->dev_handle;

aie2_pm_stop(ndev);
if (ndev->dev_status <= AIE2_DEV_INIT) {
XDNA_ERR(xdna, "device is already stopped");
return;
}

aie2_mgmt_fw_fini(ndev);
xdna_mailbox_stop_channel(ndev->mgmt_chann);
xdna_mailbox_destroy_channel(ndev->mgmt_chann);
Expand All @@ -330,6 +344,8 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna)
aie2_smu_stop(ndev);
pci_clear_master(pdev);
pci_disable_device(pdev);

ndev->dev_status = AIE2_DEV_INIT;
}

static int aie2_hw_start(struct amdxdna_dev *xdna)
Expand All @@ -340,6 +356,11 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)
u32 xdna_mailbox_intr_reg;
int mgmt_mb_irq, ret;

if (ndev->dev_status >= AIE2_DEV_START) {
XDNA_INFO(xdna, "device is already started");
return 0;
}

ret = pci_enable_device(pdev);
if (ret) {
XDNA_ERR(xdna, "failed to enable device, ret %d", ret);
Expand Down Expand Up @@ -396,18 +417,20 @@ static int aie2_hw_start(struct amdxdna_dev *xdna)
goto destroy_mbox;
}

ret = aie2_mgmt_fw_init(ndev);
ret = aie2_pm_init(ndev);
if (ret) {
XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
XDNA_ERR(xdna, "failed to init pm, ret %d", ret);
goto destroy_mgmt_chann;
}

ret = aie2_pm_start(ndev);
ret = aie2_mgmt_fw_init(ndev);
if (ret) {
XDNA_ERR(xdna, "failed to start power manager, ret %d", ret);
XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret);
goto destroy_mgmt_chann;
}

ndev->dev_status = AIE2_DEV_START;

return 0;

destroy_mgmt_chann:
Expand Down Expand Up @@ -535,10 +558,6 @@ static int aie2_init(struct amdxdna_dev *xdna)
}
xdna->dev_handle = ndev;

aie2_smu_setup(ndev);

ndev->pw_mode = POWER_MODE_DEFAULT;
ndev->clk_gate_enabled = true;
ret = aie2_hw_start(xdna);
if (ret) {
XDNA_ERR(xdna, "start npu failed, ret %d", ret);
Expand All @@ -552,11 +571,11 @@ static int aie2_init(struct amdxdna_dev *xdna)
}
ndev->total_col = min(aie2_max_col, ndev->metadata.cols);

xrs_cfg.max_dpm_level = SMU_DPM_MAX(ndev);
xrs_cfg.clk_list.num_levels = ndev->priv->smu_npu_dpm_levels;
xrs_cfg.clk_list.cu_clk_list = ndev->priv->smu_npu_dpm_clk_table;
xrs_cfg.clk_list.num_levels = ndev->max_dpm_level + 1;
for (i = 0; i < xrs_cfg.clk_list.num_levels; i++)
xrs_cfg.clk_list.cu_clk_list[i] = ndev->priv->dpm_clk_tbl[i].hclk;
xrs_cfg.sys_eff_factor = 1;
xrs_cfg.dev = xdna->ddev.dev;
xrs_cfg.ddev = &xdna->ddev;
xrs_cfg.actions = &aie2_xrs_actions;
xrs_cfg.total_col = ndev->total_col;

Expand Down Expand Up @@ -782,13 +801,11 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client,
if (!clock)
return -ENOMEM;

memcpy(clock->mp_npu_clock.name, aie2_smu_get_mpnpu_clock_name(ndev),
sizeof(clock->mp_npu_clock.name));
clock->mp_npu_clock.freq_mhz = aie2_smu_get_mpnpu_clock_freq(ndev);

memcpy(clock->h_clock.name, aie2_smu_get_hclock_name(ndev),
sizeof(clock->h_clock.name));
clock->h_clock.freq_mhz = aie2_smu_get_hclock_freq(ndev);
snprintf(clock->mp_npu_clock.name, sizeof(clock->mp_npu_clock.name),
"MP-NPU Clock");
clock->mp_npu_clock.freq_mhz = ndev->npuclk_freq;
snprintf(clock->h_clock.name, sizeof(clock->h_clock.name), "H Clock");
clock->h_clock.freq_mhz = ndev->hclk_freq;

if (copy_to_user(u64_to_user_ptr(args->buffer), clock, sizeof(*clock)))
ret = -EFAULT;
Expand Down
Loading