mirror of https://github.com/torvalds/linux.git
accel/ivpu: Add auto selection logic for job scheduler
Add ivpu_fw_sched_mode_select() function that can select scheduling mode based on HW and FW versions. This prepares for a switch to HWS on selected platforms. Reviewed-by: Karol Wachowski <karol.wachowski@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240930195322.461209-17-jacek.lawrynowicz@linux.intel.com Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
This commit is contained in:
parent
707542dd1a
commit
436b67d693
|
|
@ -54,9 +54,9 @@ u8 ivpu_pll_max_ratio = U8_MAX;
|
|||
module_param_named(pll_max_ratio, ivpu_pll_max_ratio, byte, 0644);
|
||||
MODULE_PARM_DESC(pll_max_ratio, "Maximum PLL ratio used to set NPU frequency");
|
||||
|
||||
int ivpu_sched_mode;
|
||||
int ivpu_sched_mode = IVPU_SCHED_MODE_AUTO;
|
||||
module_param_named(sched_mode, ivpu_sched_mode, int, 0444);
|
||||
MODULE_PARM_DESC(sched_mode, "Scheduler mode: 0 - Default scheduler, 1 - Force HW scheduler");
|
||||
MODULE_PARM_DESC(sched_mode, "Scheduler mode: -1 - Use default scheduler, 0 - Use OS scheduler, 1 - Use HW scheduler");
|
||||
|
||||
bool ivpu_disable_mmu_cont_pages;
|
||||
module_param_named(disable_mmu_cont_pages, ivpu_disable_mmu_cont_pages, bool, 0444);
|
||||
|
|
@ -347,7 +347,7 @@ static int ivpu_hw_sched_init(struct ivpu_device *vdev)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
ret = ivpu_jsm_hws_setup_priority_bands(vdev);
|
||||
if (ret) {
|
||||
ivpu_err(vdev, "Failed to enable hw scheduler: %d", ret);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@
|
|||
#define IVPU_PLATFORM_FPGA 3
|
||||
#define IVPU_PLATFORM_INVALID 8
|
||||
|
||||
#define IVPU_SCHED_MODE_AUTO -1
|
||||
|
||||
#define IVPU_DBG_REG BIT(0)
|
||||
#define IVPU_DBG_IRQ BIT(1)
|
||||
#define IVPU_DBG_MMU BIT(2)
|
||||
|
|
|
|||
|
|
@ -134,6 +134,15 @@ static bool is_within_range(u64 addr, size_t size, u64 range_start, size_t range
|
|||
return true;
|
||||
}
|
||||
|
||||
static u32
|
||||
ivpu_fw_sched_mode_select(struct ivpu_device *vdev, const struct vpu_firmware_header *fw_hdr)
|
||||
{
|
||||
if (ivpu_sched_mode != IVPU_SCHED_MODE_AUTO)
|
||||
return ivpu_sched_mode;
|
||||
|
||||
return VPU_SCHEDULING_MODE_OS;
|
||||
}
|
||||
|
||||
static int ivpu_fw_parse(struct ivpu_device *vdev)
|
||||
{
|
||||
struct ivpu_fw_info *fw = vdev->fw;
|
||||
|
|
@ -215,8 +224,10 @@ static int ivpu_fw_parse(struct ivpu_device *vdev)
|
|||
|
||||
fw->dvfs_mode = 0;
|
||||
|
||||
fw->sched_mode = ivpu_fw_sched_mode_select(vdev, fw_hdr);
|
||||
fw->primary_preempt_buf_size = fw_hdr->preemption_buffer_1_size;
|
||||
fw->secondary_preempt_buf_size = fw_hdr->preemption_buffer_2_size;
|
||||
ivpu_info(vdev, "Scheduler mode: %s\n", fw->sched_mode ? "HW" : "OS");
|
||||
|
||||
if (fw_hdr->ro_section_start_address && !is_within_range(fw_hdr->ro_section_start_address,
|
||||
fw_hdr->ro_section_size,
|
||||
|
|
@ -605,8 +616,8 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
|
|||
boot_params->punit_telemetry_sram_base = ivpu_hw_telemetry_offset_get(vdev);
|
||||
boot_params->punit_telemetry_sram_size = ivpu_hw_telemetry_size_get(vdev);
|
||||
boot_params->vpu_telemetry_enable = ivpu_hw_telemetry_enable_get(vdev);
|
||||
boot_params->vpu_scheduling_mode = vdev->hw->sched_mode;
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW)
|
||||
boot_params->vpu_scheduling_mode = vdev->fw->sched_mode;
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW)
|
||||
boot_params->vpu_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS;
|
||||
boot_params->dvfs_mode = vdev->fw->dvfs_mode;
|
||||
if (!IVPU_WA(disable_d0i3_msg))
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#ifndef __IVPU_FW_H__
|
||||
#define __IVPU_FW_H__
|
||||
|
||||
#include "vpu_jsm_api.h"
|
||||
|
||||
#define FW_VERSION_HEADER_SIZE SZ_4K
|
||||
#define FW_VERSION_STR_SIZE SZ_256
|
||||
|
||||
|
|
@ -36,6 +38,7 @@ struct ivpu_fw_info {
|
|||
u32 secondary_preempt_buf_size;
|
||||
u64 read_only_addr;
|
||||
u32 read_only_size;
|
||||
u32 sched_mode;
|
||||
};
|
||||
|
||||
int ivpu_fw_init(struct ivpu_device *vdev);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ struct ivpu_hw_info {
|
|||
u32 profiling_freq;
|
||||
} pll;
|
||||
u32 tile_fuse;
|
||||
u32 sched_mode;
|
||||
u32 sku;
|
||||
u16 config;
|
||||
int dma_bits;
|
||||
|
|
|
|||
|
|
@ -163,7 +163,6 @@ static int info_init_mtl(struct ivpu_device *vdev)
|
|||
hw->tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH;
|
||||
hw->sku = BTRS_MTL_TILE_SKU_BOTH;
|
||||
hw->config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO;
|
||||
hw->sched_mode = ivpu_sched_mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -178,7 +177,6 @@ static int info_init_lnl(struct ivpu_device *vdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
hw->sched_mode = ivpu_sched_mode;
|
||||
hw->tile_fuse = tile_fuse_config;
|
||||
hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev,
|
|||
u64 secondary_size = ALIGN(vdev->fw->secondary_preempt_buf_size, PAGE_SIZE);
|
||||
struct ivpu_addr_range range;
|
||||
|
||||
if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW)
|
||||
if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW)
|
||||
return 0;
|
||||
|
||||
range.start = vdev->hw->ranges.user.end - (primary_size * IVPU_NUM_CMDQS_PER_CTX);
|
||||
|
|
@ -68,7 +68,7 @@ static int ivpu_preemption_buffers_create(struct ivpu_device *vdev,
|
|||
static void ivpu_preemption_buffers_free(struct ivpu_device *vdev,
|
||||
struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq)
|
||||
{
|
||||
if (vdev->hw->sched_mode != VPU_SCHEDULING_MODE_HW)
|
||||
if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW)
|
||||
return;
|
||||
|
||||
drm_WARN_ON(&vdev->drm, !cmdq->primary_preempt_buf);
|
||||
|
|
@ -149,7 +149,7 @@ static int ivpu_register_db(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *
|
|||
struct ivpu_device *vdev = file_priv->vdev;
|
||||
int ret;
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW)
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW)
|
||||
ret = ivpu_jsm_hws_register_db(vdev, file_priv->ctx.id, cmdq->db_id, cmdq->db_id,
|
||||
cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem));
|
||||
else
|
||||
|
|
@ -184,7 +184,7 @@ ivpu_cmdq_init(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq, u16 eng
|
|||
jobq_header->tail = 0;
|
||||
wmb(); /* Flush WC buffer for jobq->header */
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
ret = ivpu_hws_cmdq_init(file_priv, cmdq, engine, priority);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -211,7 +211,7 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm
|
|||
|
||||
cmdq->db_registered = false;
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) {
|
||||
ret = ivpu_jsm_hws_destroy_cmdq(vdev, file_priv->ctx.id, cmdq->db_id);
|
||||
if (!ret)
|
||||
ivpu_dbg(vdev, JOB, "Command queue %d destroyed\n", cmdq->db_id);
|
||||
|
|
@ -335,7 +335,7 @@ void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv)
|
|||
|
||||
ivpu_cmdq_fini_all(file_priv);
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_OS)
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_OS)
|
||||
ivpu_jsm_context_release(vdev, file_priv->ctx.id);
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +361,7 @@ static int ivpu_cmdq_push_job(struct ivpu_cmdq *cmdq, struct ivpu_job *job)
|
|||
if (unlikely(ivpu_test_mode & IVPU_TEST_MODE_NULL_SUBMISSION))
|
||||
entry->flags = VPU_JOB_FLAGS_NULL_SUBMISSION_MASK;
|
||||
|
||||
if (vdev->hw->sched_mode == VPU_SCHEDULING_MODE_HW &&
|
||||
if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW &&
|
||||
(unlikely(!(ivpu_test_mode & IVPU_TEST_MODE_PREEMPTION_DISABLE)))) {
|
||||
entry->primary_preempt_buf_addr = cmdq->primary_preempt_buf->vpu_addr;
|
||||
entry->primary_preempt_buf_size = ivpu_bo_size(cmdq->primary_preempt_buf);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "ivpu_drv.h"
|
||||
#include "ivpu_fw.h"
|
||||
#include "ivpu_hw.h"
|
||||
#include "ivpu_sysfs.h"
|
||||
|
||||
|
|
@ -39,8 +41,30 @@ npu_busy_time_us_show(struct device *dev, struct device_attribute *attr, char *b
|
|||
|
||||
static DEVICE_ATTR_RO(npu_busy_time_us);
|
||||
|
||||
/**
|
||||
* DOC: sched_mode
|
||||
*
|
||||
* The sched_mode is used to report current NPU scheduling mode.
|
||||
*
|
||||
* It returns following strings:
|
||||
* - "HW" - Hardware Scheduler mode
|
||||
* - "OS" - Operating System Scheduler mode
|
||||
*
|
||||
*/
|
||||
static ssize_t
|
||||
sched_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(dev);
|
||||
struct ivpu_device *vdev = to_ivpu_device(drm);
|
||||
|
||||
return sysfs_emit(buf, "%s\n", vdev->fw->sched_mode ? "HW" : "OS");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(sched_mode);
|
||||
|
||||
static struct attribute *ivpu_dev_attrs[] = {
|
||||
&dev_attr_npu_busy_time_us.attr,
|
||||
&dev_attr_sched_mode.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue