Skip to content

Commit

Permalink
refactor power management
Browse files Browse the repository at this point in the history
  • Loading branch information
houlz0507 committed Nov 20, 2024
1 parent f4806c2 commit 21c3f54
Show file tree
Hide file tree
Showing 12 changed files with 324 additions and 498 deletions.
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
22 changes: 21 additions & 1 deletion src/driver/amdxdna/aie2_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,31 @@ 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);
u64 cur_val;
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;
}

ret = aie2_get_runtime_cfg(ndev, type, &cur_val);
if (ret) {
XDNA_ERR(ndev->xdna, "Failed to readback, ret %d", ret);
return ret;
}

if (cur_val != value) {
XDNA_ERR(ndev->xdna, "Readback val %lld mis-matched, exp %lld",
cur_val, value);
return -EFAULT;
}

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

0 comments on commit 21c3f54

Please sign in to comment.