]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
accel/amdxdna: Set default DPM level based on QoS for temporal-only mode
authorLizhi Hou <lizhi.hou@amd.com>
Fri, 24 Apr 2026 04:08:22 +0000 (21:08 -0700)
committerLizhi Hou <lizhi.hou@amd.com>
Mon, 27 Apr 2026 16:04:34 +0000 (09:04 -0700)
The QoS request provided when creating a hardware context is currently
ignored when operating in temporal-only mode. Change this to use resource
allocation through xrs_allocate_resource(), which sets the default DPM
level according to the QoS request.

When multiple hardware contexts are active, track their required DPM
levels and set the default DPM level to the highest among them.

Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260424040824.2253607-1-lizhi.hou@amd.com
drivers/accel/amdxdna/aie2_ctx.c
drivers/accel/amdxdna/aie2_pci.c
drivers/accel/amdxdna/aie2_pci.h
drivers/accel/amdxdna/aie2_pm.c
drivers/accel/amdxdna/aie2_solver.c
drivers/accel/amdxdna/npu1_regs.c
drivers/accel/amdxdna/npu4_regs.c
drivers/accel/amdxdna/npu5_regs.c
drivers/accel/amdxdna/npu6_regs.c

index 3b0feba448c498a6e13aef4d4d28dbc5aba4147f..139825ac85155af7780e9ce3a4fe0db32b92f697 100644 (file)
@@ -546,22 +546,24 @@ static int aie2_alloc_resource(struct amdxdna_hwctx *hwctx)
 {
        struct amdxdna_dev *xdna = hwctx->client->xdna;
        struct alloc_requests *xrs_req;
+       u32 temporal_only_col = 0;
        int ret;
 
-       if (AIE_FEATURE_ON(&xdna->dev_handle->aie, AIE2_TEMPORAL_ONLY)) {
-               hwctx->num_unused_col = xdna->dev_handle->total_col - hwctx->num_col;
-               hwctx->num_col = xdna->dev_handle->total_col;
-               return aie2_create_context(xdna->dev_handle, hwctx);
-       }
-
        xrs_req = kzalloc_obj(*xrs_req);
        if (!xrs_req)
                return -ENOMEM;
 
-       xrs_req->cdo.start_cols = hwctx->col_list;
-       xrs_req->cdo.cols_len = hwctx->col_list_len;
-       xrs_req->cdo.ncols = hwctx->num_col;
-       xrs_req->cdo.qos_cap.opc = hwctx->max_opc;
+       if (AIE_FEATURE_ON(&xdna->dev_handle->aie, AIE2_TEMPORAL_ONLY)) {
+               xrs_req->cdo.start_cols = &temporal_only_col;
+               xrs_req->cdo.cols_len = 1;
+               xrs_req->cdo.ncols = xdna->dev_handle->total_col;
+       } else {
+               xrs_req->cdo.start_cols = hwctx->col_list;
+               xrs_req->cdo.cols_len = hwctx->col_list_len;
+               xrs_req->cdo.ncols = hwctx->num_col;
+       }
+       /* Use platform opc */
+       xrs_req->cdo.qos_cap.opc = xdna->dev_handle->priv->col_opc * hwctx->num_col;
 
        xrs_req->rqos.gops = hwctx->qos.gops;
        xrs_req->rqos.fps = hwctx->qos.fps;
@@ -585,15 +587,9 @@ static void aie2_release_resource(struct amdxdna_hwctx *hwctx)
        struct amdxdna_dev *xdna = hwctx->client->xdna;
        int ret;
 
-       if (AIE_FEATURE_ON(&xdna->dev_handle->aie, AIE2_TEMPORAL_ONLY)) {
-               ret = aie2_destroy_context(xdna->dev_handle, hwctx);
-               if (ret && ret != -ENODEV)
-                       XDNA_ERR(xdna, "Destroy temporal only context failed, ret %d", ret);
-       } else {
-               ret = xrs_release_resource(xdna->xrs_hdl, (uintptr_t)hwctx);
-               if (ret)
-                       XDNA_ERR(xdna, "Release AIE resource failed, ret %d", ret);
-       }
+       ret = xrs_release_resource(xdna->xrs_hdl, (uintptr_t)hwctx);
+       if (ret)
+               XDNA_ERR(xdna, "Release AIE resource failed, ret %d", ret);
 }
 
 static int aie2_ctx_syncobj_create(struct amdxdna_hwctx *hwctx)
index 1d1fb012294af803e91e83dc3999723eb99ac0a1..a07e453a17213bc2245459033dbdf3e93b7ed81b 100644 (file)
@@ -246,6 +246,7 @@ static int aie2_xrs_load(void *cb_arg, struct xrs_action_load *action)
        xdna = hwctx->client->xdna;
 
        hwctx->start_col = action->part.start_col;
+       hwctx->num_unused_col = action->part.ncols - hwctx->num_col;
        hwctx->num_col = action->part.ncols;
        ret = aie2_create_context(xdna->dev_handle, hwctx);
        if (ret)
index c44616065058e6e3670b5040e509bfabdcdcaf0f..f1207317567652cbf7e40906c2a40f9c7a19598d 100644 (file)
@@ -237,6 +237,7 @@ struct amdxdna_dev_priv {
 #define COL_ALIGN_NONE   0
 #define COL_ALIGN_NATURE 1
        u32                             col_align;
+       u32                             col_opc;
        u32                             mbox_dev_addr;
        /* If mbox_size is 0, use BAR size. See MBOX_SIZE macro */
        u32                             mbox_size;
index 786d688bd82c76946841ed3f5f1ea450538616df..d9ccd7fc8a6dabec1ee3819d2be9461231b27ffa 100644 (file)
@@ -74,7 +74,7 @@ int aie2_pm_init(struct amdxdna_dev_hdl *ndev)
                return ret;
 
        ndev->pw_mode = POWER_MODE_DEFAULT;
-       ndev->dft_dpm_level = ndev->max_dpm_level;
+       ndev->dft_dpm_level = 0;
 
        return 0;
 }
index 3611e3268d7913b14bf2abfed967100e83320d1f..6f3ee77d5264fe23ec031006bf80386d1cb40fbe 100644 (file)
@@ -52,7 +52,7 @@ static u32 calculate_gops(struct aie_qos *rqos)
        u32 service_rate = 0;
 
        if (rqos->latency)
-               service_rate = (1000 / rqos->latency);
+               service_rate = max_t(u32, 1000 / rqos->latency, 1);
 
        if (rqos->fps > service_rate)
                return rqos->fps * rqos->gops;
@@ -348,6 +348,7 @@ int xrs_release_resource(void *hdl, u64 rid)
 {
        struct solver_state *xrs = hdl;
        struct solver_node *node;
+       u32 level = 0;
 
        node = rg_search_node(&xrs->rgp, rid);
        if (!node) {
@@ -358,6 +359,13 @@ int xrs_release_resource(void *hdl, u64 rid)
        xrs->cfg.actions->unload(node->cb_arg);
        remove_solver_node(&xrs->rgp, node);
 
+       /* set the dpm level which fits all the sessions */
+       list_for_each_entry(node, &xrs->rgp.node_list, list) {
+               if (node->dpm_level > level)
+                       level = node->dpm_level;
+       }
+       xrs->cfg.actions->set_dft_dpm_level(xrs->cfg.ddev, level);
+
        return 0;
 }
 
index d7e50c6b06efdfea60bbcd7f1b0a077e6007310a..4e48c030a69f47f33232efaa9eb44b615f1a01c8 100644 (file)
@@ -97,6 +97,7 @@ static const struct amdxdna_dev_priv npu1_dev_priv = {
        .rt_config      = npu1_default_rt_cfg,
        .dpm_clk_tbl    = npu1_dpm_clk_table,
        .col_align      = COL_ALIGN_NONE,
+       .col_opc        = 2048,
        .mbox_dev_addr  = NPU1_MBOX_BAR_BASE,
        .mbox_size      = 0, /* Use BAR size */
        .sram_dev_addr  = NPU1_SRAM_BAR_BASE,
index 935999ced70fd9a2f826911f9a843f1e9c9fbd8a..eddc31803a5081ee0c73be7c9eebcaab8e41139d 100644 (file)
@@ -160,6 +160,7 @@ static const struct amdxdna_dev_priv npu4_dev_priv = {
        .rt_config      = npu4_default_rt_cfg,
        .dpm_clk_tbl    = npu4_dpm_clk_table,
        .col_align      = COL_ALIGN_NATURE,
+       .col_opc        = 4096,
        .mbox_dev_addr  = NPU4_MBOX_BAR_BASE,
        .mbox_size      = 0, /* Use BAR size */
        .sram_dev_addr  = NPU4_SRAM_BAR_BASE,
index 795bd19968457058870199f0b98df588822edaa8..a9102978e4a8e1b28491cae081784761dccefe4e 100644 (file)
@@ -67,6 +67,7 @@ static const struct amdxdna_dev_priv npu5_dev_priv = {
        .rt_config      = npu4_default_rt_cfg,
        .dpm_clk_tbl    = npu4_dpm_clk_table,
        .col_align      = COL_ALIGN_NATURE,
+       .col_opc        = 4096,
        .mbox_dev_addr  = NPU5_MBOX_BAR_BASE,
        .mbox_size      = 0, /* Use BAR size */
        .sram_dev_addr  = NPU5_SRAM_BAR_BASE,
index 3125d1ce45ab0c61e730e21c395911c312d64c98..e0db3a09740b208829a4aa57c55f591a8099118a 100644 (file)
@@ -67,6 +67,7 @@ static const struct amdxdna_dev_priv npu6_dev_priv = {
        .rt_config      = npu4_default_rt_cfg,
        .dpm_clk_tbl    = npu4_dpm_clk_table,
        .col_align      = COL_ALIGN_NATURE,
+       .col_opc        = 4096,
        .mbox_dev_addr  = NPU6_MBOX_BAR_BASE,
        .mbox_size      = 0, /* Use BAR size */
        .sram_dev_addr  = NPU6_SRAM_BAR_BASE,