Commit 8a27ad81 authored by Wachowski, Karol's avatar Wachowski, Karol Committed by Jacek Lawrynowicz

accel/ivpu: Split IP and buttress code

The NPU device consists of two parts: NPU buttress and NPU IP.
Buttress is a platform specific part that integrates the NPU IP with
the CPU.
NPU IP is the platform agnostic part that does the inference.

This separation enables support for multiple platforms using
a single NPU IP, so for example NPU IP 37XX could be integrated into
MTL and LNL platforms.
Signed-off-by: default avatarWachowski, Karol <karol.wachowski@intel.com>
Signed-off-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240515113006.457472-3-jacek.lawrynowicz@linux.intel.com
parent 302d5832
......@@ -6,8 +6,9 @@ intel_vpu-y := \
ivpu_fw.o \
ivpu_fw_log.o \
ivpu_gem.o \
ivpu_hw_37xx.o \
ivpu_hw_40xx.o \
ivpu_hw.o \
ivpu_hw_btrs.o \
ivpu_hw_ip.o \
ivpu_ipc.o \
ivpu_job.o \
ivpu_jsm_msg.o \
......
......@@ -409,7 +409,7 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
debugfs_create_file("resume_engine", 0200, debugfs_root, vdev,
&ivpu_resume_engine_fops);
if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX)
if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX)
debugfs_create_file("fw_profiling_freq_drive", 0200,
debugfs_root, vdev, &fw_profiling_freq_fops);
}
......@@ -464,9 +464,11 @@ static int ivpu_irq_init(struct ivpu_device *vdev)
return ret;
}
ivpu_irq_handlers_init(vdev);
vdev->irq = pci_irq_vector(pdev, 0);
ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, ivpu_hw_irq_handler,
ivpu_irq_thread_handler, IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
if (ret)
ivpu_err(vdev, "Failed to request an IRQ %d\n", ret);
......@@ -543,13 +545,10 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
if (!vdev->pm)
return -ENOMEM;
if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX) {
vdev->hw->ops = &ivpu_hw_40xx_ops;
if (ivpu_hw_ip_gen(vdev) >= IVPU_HW_IP_40XX)
vdev->hw->dma_bits = 48;
} else {
vdev->hw->ops = &ivpu_hw_37xx_ops;
else
vdev->hw->dma_bits = 38;
}
vdev->platform = IVPU_PLATFORM_INVALID;
vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
......@@ -578,7 +577,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
goto err_xa_destroy;
/* Init basic HW info based on buttress registers which are accessible before power up */
ret = ivpu_hw_info_init(vdev);
ret = ivpu_hw_init(vdev);
if (ret)
goto err_xa_destroy;
......
......@@ -27,8 +27,13 @@
#define PCI_DEVICE_ID_ARL 0xad1d
#define PCI_DEVICE_ID_LNL 0x643e
#define IVPU_HW_37XX 37
#define IVPU_HW_40XX 40
#define IVPU_HW_IP_37XX 37
#define IVPU_HW_IP_40XX 40
#define IVPU_HW_IP_50XX 50
#define IVPU_HW_IP_60XX 60
#define IVPU_HW_BTRS_MTL 1
#define IVPU_HW_BTRS_LNL 2
#define IVPU_GLOBAL_CONTEXT_MMU_SSID 0
/* SSID 1 is used by the VPU to represent reserved context */
......@@ -198,16 +203,32 @@ static inline u16 ivpu_device_id(struct ivpu_device *vdev)
return to_pci_dev(vdev->drm.dev)->device;
}
static inline int ivpu_hw_gen(struct ivpu_device *vdev)
static inline int ivpu_hw_ip_gen(struct ivpu_device *vdev)
{
switch (ivpu_device_id(vdev)) {
case PCI_DEVICE_ID_MTL:
case PCI_DEVICE_ID_ARL:
return IVPU_HW_IP_37XX;
case PCI_DEVICE_ID_LNL:
return IVPU_HW_IP_40XX;
default:
dump_stack();
ivpu_err(vdev, "Unknown NPU IP generation\n");
return 0;
}
}
static inline int ivpu_hw_btrs_gen(struct ivpu_device *vdev)
{
switch (ivpu_device_id(vdev)) {
case PCI_DEVICE_ID_MTL:
case PCI_DEVICE_ID_ARL:
return IVPU_HW_37XX;
return IVPU_HW_BTRS_MTL;
case PCI_DEVICE_ID_LNL:
return IVPU_HW_40XX;
return IVPU_HW_BTRS_LNL;
default:
ivpu_err(vdev, "Unknown NPU device\n");
dump_stack();
ivpu_err(vdev, "Unknown buttress generation\n");
return 0;
}
}
......
......@@ -54,10 +54,10 @@ static struct {
int gen;
const char *name;
} fw_names[] = {
{ IVPU_HW_37XX, "vpu_37xx.bin" },
{ IVPU_HW_37XX, "intel/vpu/vpu_37xx_v0.0.bin" },
{ IVPU_HW_40XX, "vpu_40xx.bin" },
{ IVPU_HW_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
{ IVPU_HW_IP_37XX, "vpu_37xx.bin" },
{ IVPU_HW_IP_37XX, "intel/vpu/vpu_37xx_v0.0.bin" },
{ IVPU_HW_IP_40XX, "vpu_40xx.bin" },
{ IVPU_HW_IP_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
};
static int ivpu_fw_request(struct ivpu_device *vdev)
......@@ -73,7 +73,7 @@ static int ivpu_fw_request(struct ivpu_device *vdev)
}
for (i = 0; i < ARRAY_SIZE(fw_names); i++) {
if (fw_names[i].gen != ivpu_hw_gen(vdev))
if (fw_names[i].gen != ivpu_hw_ip_gen(vdev))
continue;
ret = firmware_request_nowarn(&vdev->fw->file, fw_names[i].name, vdev->drm.dev);
......@@ -246,7 +246,7 @@ static int ivpu_fw_update_global_range(struct ivpu_device *vdev)
return -EINVAL;
}
ivpu_hw_init_range(&vdev->hw->ranges.global, start, size);
ivpu_hw_range_init(&vdev->hw->ranges.global, start, size);
return 0;
}
......@@ -511,7 +511,7 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
boot_params->magic = VPU_BOOT_PARAMS_MAGIC;
boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
boot_params->frequency = ivpu_hw_reg_pll_freq_get(vdev);
boot_params->frequency = ivpu_hw_pll_freq_get(vdev);
/*
* This param is a debug firmware feature. It switches default clock
......@@ -568,9 +568,9 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
boot_params->verbose_tracing_buff_addr = vdev->fw->mem_log_verb->vpu_addr;
boot_params->verbose_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_verb);
boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev);
boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev);
boot_params->vpu_telemetry_enable = ivpu_hw_reg_telemetry_enable_get(vdev);
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_focus_present_timer_ms = IVPU_FOCUS_PRESENT_TIMER_MS;
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 - 2024 Intel Corporation
*/
#include "ivpu_drv.h"
#include "ivpu_hw.h"
#include "ivpu_hw_btrs.h"
#include "ivpu_hw_ip.h"
#include <linux/dmi.h>
static char *platform_to_str(u32 platform)
{
switch (platform) {
case IVPU_PLATFORM_SILICON:
return "SILICON";
case IVPU_PLATFORM_SIMICS:
return "SIMICS";
case IVPU_PLATFORM_FPGA:
return "FPGA";
default:
return "Invalid platform";
}
}
static const struct dmi_system_id dmi_platform_simulation[] = {
{
.ident = "Intel Simics",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "lnlrvp"),
DMI_MATCH(DMI_BOARD_VERSION, "1.0"),
DMI_MATCH(DMI_BOARD_SERIAL, "123456789"),
},
},
{
.ident = "Intel Simics",
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "Simics"),
},
},
{ }
};
static void platform_init(struct ivpu_device *vdev)
{
if (dmi_check_system(dmi_platform_simulation))
vdev->platform = IVPU_PLATFORM_SIMICS;
else
vdev->platform = IVPU_PLATFORM_SILICON;
ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n",
platform_to_str(vdev->platform), vdev->platform);
}
static void wa_init(struct ivpu_device *vdev)
{
vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
vdev->wa.clear_runtime_mem = false;
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);
if (ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL)
vdev->wa.disable_clock_relinquish = true;
IVPU_PRINT_WA(punit_disabled);
IVPU_PRINT_WA(clear_runtime_mem);
IVPU_PRINT_WA(interrupt_clear_with_0);
IVPU_PRINT_WA(disable_clock_relinquish);
}
static void timeouts_init(struct ivpu_device *vdev)
{
if (ivpu_is_fpga(vdev)) {
vdev->timeout.boot = 100000;
vdev->timeout.jsm = 50000;
vdev->timeout.tdr = 2000000;
vdev->timeout.reschedule_suspend = 1000;
vdev->timeout.autosuspend = -1;
vdev->timeout.d0i3_entry_msg = 500;
} else if (ivpu_is_simics(vdev)) {
vdev->timeout.boot = 50;
vdev->timeout.jsm = 500;
vdev->timeout.tdr = 10000;
vdev->timeout.reschedule_suspend = 10;
vdev->timeout.autosuspend = -1;
vdev->timeout.d0i3_entry_msg = 100;
} else {
vdev->timeout.boot = 1000;
vdev->timeout.jsm = 500;
vdev->timeout.tdr = 2000;
vdev->timeout.reschedule_suspend = 10;
vdev->timeout.autosuspend = 10;
vdev->timeout.d0i3_entry_msg = 5;
}
}
static void memory_ranges_init(struct ivpu_device *vdev)
{
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
ivpu_hw_range_init(&vdev->hw->ranges.user, 0xc0000000, 255 * SZ_1M);
ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x180000000, SZ_2G);
ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G);
} else {
ivpu_hw_range_init(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
ivpu_hw_range_init(&vdev->hw->ranges.user, 0x80000000, SZ_256M);
ivpu_hw_range_init(&vdev->hw->ranges.shave, 0x80000000 + SZ_256M, SZ_2G - SZ_256M);
ivpu_hw_range_init(&vdev->hw->ranges.dma, 0x200000000, SZ_8G);
}
}
static int wp_enable(struct ivpu_device *vdev)
{
return ivpu_hw_btrs_wp_drive(vdev, true);
}
static int wp_disable(struct ivpu_device *vdev)
{
return ivpu_hw_btrs_wp_drive(vdev, false);
}
int ivpu_hw_power_up(struct ivpu_device *vdev)
{
int ret;
ret = ivpu_hw_btrs_d0i3_disable(vdev);
if (ret)
ivpu_warn(vdev, "Failed to disable D0I3: %d\n", ret);
ret = wp_enable(vdev);
if (ret) {
ivpu_err(vdev, "Failed to enable workpoint: %d\n", ret);
return ret;
}
if (ivpu_hw_btrs_gen(vdev) >= IVPU_HW_BTRS_LNL) {
if (IVPU_WA(disable_clock_relinquish))
ivpu_hw_btrs_clock_relinquish_disable_lnl(vdev);
ivpu_hw_btrs_profiling_freq_reg_set_lnl(vdev);
ivpu_hw_btrs_ats_print_lnl(vdev);
}
ret = ivpu_hw_ip_host_ss_configure(vdev);
if (ret) {
ivpu_err(vdev, "Failed to configure host SS: %d\n", ret);
return ret;
}
ivpu_hw_ip_idle_gen_disable(vdev);
ret = ivpu_hw_btrs_wait_for_clock_res_own_ack(vdev);
if (ret) {
ivpu_err(vdev, "Timed out waiting for clock resource own ACK\n");
return ret;
}
ret = ivpu_hw_ip_pwr_domain_enable(vdev);
if (ret) {
ivpu_err(vdev, "Failed to enable power domain: %d\n", ret);
return ret;
}
ret = ivpu_hw_ip_host_ss_axi_enable(vdev);
if (ret) {
ivpu_err(vdev, "Failed to enable AXI: %d\n", ret);
return ret;
}
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_LNL)
ivpu_hw_btrs_set_port_arbitration_weights_lnl(vdev);
ret = ivpu_hw_ip_top_noc_enable(vdev);
if (ret)
ivpu_err(vdev, "Failed to enable TOP NOC: %d\n", ret);
return ret;
}
static void save_d0i3_entry_timestamp(struct ivpu_device *vdev)
{
vdev->hw->d0i3_entry_host_ts = ktime_get_boottime();
vdev->hw->d0i3_entry_vpu_ts = ivpu_hw_ip_read_perf_timer_counter(vdev);
}
int ivpu_hw_reset(struct ivpu_device *vdev)
{
int ret = 0;
if (ivpu_hw_btrs_ip_reset(vdev)) {
ivpu_err(vdev, "Failed to reset NPU IP\n");
ret = -EIO;
}
if (wp_disable(vdev)) {
ivpu_err(vdev, "Failed to disable workpoint\n");
ret = -EIO;
}
return ret;
}
int ivpu_hw_power_down(struct ivpu_device *vdev)
{
int ret = 0;
save_d0i3_entry_timestamp(vdev);
if (!ivpu_hw_is_idle(vdev))
ivpu_warn(vdev, "NPU not idle during power down\n");
if (ivpu_hw_reset(vdev)) {
ivpu_err(vdev, "Failed to reset NPU\n");
ret = -EIO;
}
if (ivpu_hw_btrs_d0i3_enable(vdev)) {
ivpu_err(vdev, "Failed to enter D0I3\n");
ret = -EIO;
}
return ret;
}
int ivpu_hw_init(struct ivpu_device *vdev)
{
ivpu_hw_btrs_info_init(vdev);
ivpu_hw_btrs_freq_ratios_init(vdev);
memory_ranges_init(vdev);
platform_init(vdev);
wa_init(vdev);
timeouts_init(vdev);
return 0;
}
int ivpu_hw_boot_fw(struct ivpu_device *vdev)
{
int ret;
ivpu_hw_ip_snoop_disable(vdev);
ivpu_hw_ip_tbu_mmu_enable(vdev);
ret = ivpu_hw_ip_soc_cpu_boot(vdev);
if (ret)
ivpu_err(vdev, "Failed to boot SOC CPU: %d\n", ret);
return ret;
}
void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
{
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
return;
}
if (enable)
vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
else
vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
}
void ivpu_irq_handlers_init(struct ivpu_device *vdev)
{
if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_37xx;
else
vdev->hw->irq.ip_irq_handler = ivpu_hw_ip_irq_handler_40xx;
if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_mtl;
else
vdev->hw->irq.btrs_irq_handler = ivpu_hw_btrs_irq_handler_lnl;
}
void ivpu_hw_irq_enable(struct ivpu_device *vdev)
{
ivpu_hw_ip_irq_enable(vdev);
ivpu_hw_btrs_irq_enable(vdev);
}
void ivpu_hw_irq_disable(struct ivpu_device *vdev)
{
ivpu_hw_btrs_irq_disable(vdev);
ivpu_hw_ip_irq_disable(vdev);
}
irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr)
{
bool ip_handled, btrs_handled, wake_thread = false;
struct ivpu_device *vdev = ptr;
ivpu_hw_btrs_global_int_disable(vdev);
btrs_handled = ivpu_hw_btrs_irq_handler(vdev, irq);
if (!ivpu_hw_is_idle((vdev)) || !btrs_handled)
ip_handled = ivpu_hw_ip_irq_handler(vdev, irq, &wake_thread);
else
ip_handled = false;
/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
ivpu_hw_btrs_global_int_enable(vdev);
if (wake_thread)
return IRQ_WAKE_THREAD;
if (ip_handled || btrs_handled)
return IRQ_HANDLED;
return IRQ_NONE;
}
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020 - 2024 Intel Corporation
*/
#ifndef __IVPU_HW_H__
#define __IVPU_HW_H__
#include "ivpu_drv.h"
struct ivpu_hw_ops {
int (*info_init)(struct ivpu_device *vdev);
int (*power_up)(struct ivpu_device *vdev);
int (*boot_fw)(struct ivpu_device *vdev);
int (*power_down)(struct ivpu_device *vdev);
int (*reset)(struct ivpu_device *vdev);
bool (*is_idle)(struct ivpu_device *vdev);
int (*wait_for_idle)(struct ivpu_device *vdev);
void (*wdt_disable)(struct ivpu_device *vdev);
void (*diagnose_failure)(struct ivpu_device *vdev);
u32 (*profiling_freq_get)(struct ivpu_device *vdev);
void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
u32 (*ratio_to_freq)(struct ivpu_device *vdev, u32 ratio);
u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev);
void (*reg_db_set)(struct ivpu_device *vdev, u32 db_id);
u32 (*reg_ipc_rx_addr_get)(struct ivpu_device *vdev);
u32 (*reg_ipc_rx_count_get)(struct ivpu_device *vdev);
void (*reg_ipc_tx_set)(struct ivpu_device *vdev, u32 vpu_addr);
void (*irq_clear)(struct ivpu_device *vdev);
void (*irq_enable)(struct ivpu_device *vdev);
void (*irq_disable)(struct ivpu_device *vdev);
irqreturn_t (*irq_handler)(int irq, void *ptr);
};
#include "ivpu_hw_btrs.h"
#include "ivpu_hw_ip.h"
struct ivpu_addr_range {
resource_size_t start;
......@@ -41,7 +16,10 @@ struct ivpu_addr_range {
};
struct ivpu_hw_info {
const struct ivpu_hw_ops *ops;
struct {
bool (*btrs_irq_handler)(struct ivpu_device *vdev, int irq);
bool (*ip_irq_handler)(struct ivpu_device *vdev, int irq, bool *wake_thread);
} irq;
struct {
struct ivpu_addr_range global;
struct ivpu_addr_range user;
......@@ -67,140 +45,107 @@ struct ivpu_hw_info {
u64 d0i3_entry_vpu_ts;
};
extern const struct ivpu_hw_ops ivpu_hw_37xx_ops;
extern const struct ivpu_hw_ops ivpu_hw_40xx_ops;
static inline int ivpu_hw_info_init(struct ivpu_device *vdev)
{
return vdev->hw->ops->info_init(vdev);
};
static inline int ivpu_hw_power_up(struct ivpu_device *vdev)
{
ivpu_dbg(vdev, PM, "HW power up\n");
return vdev->hw->ops->power_up(vdev);
};
int ivpu_hw_init(struct ivpu_device *vdev);
int ivpu_hw_power_up(struct ivpu_device *vdev);
int ivpu_hw_power_down(struct ivpu_device *vdev);
int ivpu_hw_reset(struct ivpu_device *vdev);
int ivpu_hw_boot_fw(struct ivpu_device *vdev);
void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable);
void ivpu_irq_handlers_init(struct ivpu_device *vdev);
void ivpu_hw_irq_enable(struct ivpu_device *vdev);
void ivpu_hw_irq_disable(struct ivpu_device *vdev);
irqreturn_t ivpu_hw_irq_handler(int irq, void *ptr);
static inline int ivpu_hw_boot_fw(struct ivpu_device *vdev)
static inline u32 ivpu_hw_btrs_irq_handler(struct ivpu_device *vdev, int irq)
{
return vdev->hw->ops->boot_fw(vdev);
};
static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
{
return vdev->hw->ops->is_idle(vdev);
};
static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
{
return vdev->hw->ops->wait_for_idle(vdev);
};
static inline int ivpu_hw_power_down(struct ivpu_device *vdev)
{
ivpu_dbg(vdev, PM, "HW power down\n");
return vdev->hw->ops->power_down(vdev);
};
static inline int ivpu_hw_reset(struct ivpu_device *vdev)
{
ivpu_dbg(vdev, PM, "HW reset\n");
return vdev->hw->ops->reset(vdev);
};
static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
{
vdev->hw->ops->wdt_disable(vdev);
};
return vdev->hw->irq.btrs_irq_handler(vdev, irq);
}
static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
static inline u32 ivpu_hw_ip_irq_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
{
return vdev->hw->ops->profiling_freq_get(vdev);
};
return vdev->hw->irq.ip_irq_handler(vdev, irq, wake_thread);
}
static inline void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
static inline void ivpu_hw_range_init(struct ivpu_addr_range *range, u64 start, u64 size)
{
return vdev->hw->ops->profiling_freq_drive(vdev, enable);
};
range->start = start;
range->end = start + size;
}
/* Register indirect accesses */
static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
{
return vdev->hw->ops->reg_pll_freq_get(vdev);
};
return range->end - range->start;
}
static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
{
return vdev->hw->ops->ratio_to_freq(vdev, ratio);
return ivpu_hw_btrs_ratio_to_freq(vdev, ratio);
}
static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev)
static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
{
return vdev->hw->ops->reg_telemetry_offset_get(vdev);
};
ivpu_hw_ip_irq_clear(vdev);
}
static inline u32 ivpu_hw_reg_telemetry_size_get(struct ivpu_device *vdev)
static inline u32 ivpu_hw_pll_freq_get(struct ivpu_device *vdev)
{
return vdev->hw->ops->reg_telemetry_size_get(vdev);
};
return ivpu_hw_btrs_pll_freq_get(vdev);
}
static inline u32 ivpu_hw_reg_telemetry_enable_get(struct ivpu_device *vdev)
static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
{
return vdev->hw->ops->reg_telemetry_enable_get(vdev);
};
return vdev->hw->pll.profiling_freq;
}
static inline void ivpu_hw_reg_db_set(struct ivpu_device *vdev, u32 db_id)
static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
{
vdev->hw->ops->reg_db_set(vdev, db_id);
};
ivpu_hw_ip_diagnose_failure(vdev);
ivpu_hw_btrs_diagnose_failure(vdev);
}
static inline u32 ivpu_hw_reg_ipc_rx_addr_get(struct ivpu_device *vdev)
static inline u32 ivpu_hw_telemetry_offset_get(struct ivpu_device *vdev)
{
return vdev->hw->ops->reg_ipc_rx_addr_get(vdev);
};
return ivpu_hw_btrs_telemetry_offset_get(vdev);
}
static inline u32 ivpu_hw_reg_ipc_rx_count_get(struct ivpu_device *vdev)
static inline u32 ivpu_hw_telemetry_size_get(struct ivpu_device *vdev)
{
return vdev->hw->ops->reg_ipc_rx_count_get(vdev);
};
return ivpu_hw_btrs_telemetry_size_get(vdev);
}
static inline void ivpu_hw_reg_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
static inline u32 ivpu_hw_telemetry_enable_get(struct ivpu_device *vdev)
{
vdev->hw->ops->reg_ipc_tx_set(vdev, vpu_addr);
};
return ivpu_hw_btrs_telemetry_enable_get(vdev);
}
static inline void ivpu_hw_irq_clear(struct ivpu_device *vdev)
static inline bool ivpu_hw_is_idle(struct ivpu_device *vdev)
{
vdev->hw->ops->irq_clear(vdev);
};
return ivpu_hw_btrs_is_idle(vdev);
}
static inline void ivpu_hw_irq_enable(struct ivpu_device *vdev)
static inline int ivpu_hw_wait_for_idle(struct ivpu_device *vdev)
{
vdev->hw->ops->irq_enable(vdev);
};
return ivpu_hw_btrs_wait_for_idle(vdev);
}
static inline void ivpu_hw_irq_disable(struct ivpu_device *vdev)
static inline void ivpu_hw_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
{
vdev->hw->ops->irq_disable(vdev);
};
ivpu_hw_ip_ipc_tx_set(vdev, vpu_addr);
}
static inline void ivpu_hw_init_range(struct ivpu_addr_range *range, u64 start, u64 size)
static inline void ivpu_hw_db_set(struct ivpu_device *vdev, u32 db_id)
{
range->start = start;
range->end = start + size;
ivpu_hw_ip_db_set(vdev, db_id);
}
static inline u64 ivpu_hw_range_size(const struct ivpu_addr_range *range)
static inline u32 ivpu_hw_ipc_rx_addr_get(struct ivpu_device *vdev)
{
return range->end - range->start;
return ivpu_hw_ip_ipc_rx_addr_get(vdev);
}
static inline void ivpu_hw_diagnose_failure(struct ivpu_device *vdev)
static inline u32 ivpu_hw_ipc_rx_count_get(struct ivpu_device *vdev)
{
vdev->hw->ops->diagnose_failure(vdev);
return ivpu_hw_ip_ipc_rx_count_get(vdev);
}
#endif /* __IVPU_HW_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_HW_BTRS_H__
#define __IVPU_HW_BTRS_H__
#include "ivpu_drv.h"
#include "ivpu_hw_37xx_reg.h"
#include "ivpu_hw_40xx_reg.h"
#include "ivpu_hw_reg_io.h"
#define PLL_PROFILING_FREQ_DEFAULT 38400000
#define PLL_PROFILING_FREQ_HIGH 400000000
#define PLL_RATIO_TO_FREQ(x) ((x) * PLL_REF_CLK_FREQ)
int ivpu_hw_btrs_info_init(struct ivpu_device *vdev);
void ivpu_hw_btrs_freq_ratios_init(struct ivpu_device *vdev);
int ivpu_hw_btrs_irqs_clear_with_0_mtl(struct ivpu_device *vdev);
int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable);
int ivpu_hw_btrs_wait_for_clock_res_own_ack(struct ivpu_device *vdev);
int ivpu_hw_btrs_d0i3_enable(struct ivpu_device *vdev);
int ivpu_hw_btrs_d0i3_disable(struct ivpu_device *vdev);
void ivpu_hw_btrs_set_port_arbitration_weights_lnl(struct ivpu_device *vdev);
bool ivpu_hw_btrs_is_idle(struct ivpu_device *vdev);
int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev);
int ivpu_hw_btrs_ip_reset(struct ivpu_device *vdev);
void ivpu_hw_btrs_profiling_freq_reg_set_lnl(struct ivpu_device *vdev);
void ivpu_hw_btrs_ats_print_lnl(struct ivpu_device *vdev);
void ivpu_hw_btrs_clock_relinquish_disable_lnl(struct ivpu_device *vdev);
bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq);
bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq);
void ivpu_hw_btrs_dct_drive(struct ivpu_device *vdev, u32 dct_val);
u32 ivpu_hw_btrs_pll_freq_get(struct ivpu_device *vdev);
u32 ivpu_hw_btrs_ratio_to_freq(struct ivpu_device *vdev, u32 ratio);
u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev);
u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev);
u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev);
void ivpu_hw_btrs_global_int_enable(struct ivpu_device *vdev);
void ivpu_hw_btrs_global_int_disable(struct ivpu_device *vdev);
void ivpu_hw_btrs_irq_enable(struct ivpu_device *vdev);
void ivpu_hw_btrs_irq_disable(struct ivpu_device *vdev);
void ivpu_hw_btrs_diagnose_failure(struct ivpu_device *vdev);
#endif /* __IVPU_HW_BTRS_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020-2024 Intel Corporation
*/
#ifndef __IVPU_HW_IP_H__
#define __IVPU_HW_IP_H__
#include "ivpu_drv.h"
int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev);
void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev);
void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev);
int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev);
int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev);
int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev);
u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev);
void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev);
void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev);
int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev);
void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev);
void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev);
u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev);
void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev);
bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq, bool *wake_thread);
bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq, bool *wake_thread);
void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id);
u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev);
void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr);
void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev);
void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev);
void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev);
void ivpu_hw_ip_fabric_req_override_enable_50xx(struct ivpu_device *vdev);
void ivpu_hw_ip_fabric_req_override_disable_50xx(struct ivpu_device *vdev);
#endif /* __IVPU_HW_IP_H__ */
......@@ -129,7 +129,7 @@ static void ivpu_ipc_tx_release(struct ivpu_device *vdev, u32 vpu_addr)
static void ivpu_ipc_tx(struct ivpu_device *vdev, u32 vpu_addr)
{
ivpu_hw_reg_ipc_tx_set(vdev, vpu_addr);
ivpu_hw_ipc_tx_set(vdev, vpu_addr);
}
static void
......@@ -392,8 +392,8 @@ void ivpu_ipc_irq_handler(struct ivpu_device *vdev, bool *wake_thread)
* Driver needs to purge all messages from IPC FIFO to clear IPC interrupt.
* Without purge IPC FIFO to 0 next IPC interrupts won't be generated.
*/
while (ivpu_hw_reg_ipc_rx_count_get(vdev)) {
vpu_addr = ivpu_hw_reg_ipc_rx_addr_get(vdev);
while (ivpu_hw_ipc_rx_count_get(vdev)) {
vpu_addr = ivpu_hw_ipc_rx_addr_get(vdev);
if (vpu_addr == REG_IO_ERROR) {
ivpu_err_ratelimited(vdev, "Failed to read IPC rx addr register\n");
return;
......
......@@ -27,7 +27,7 @@
static void ivpu_cmdq_ring_db(struct ivpu_device *vdev, struct ivpu_cmdq *cmdq)
{
ivpu_hw_reg_db_set(vdev, cmdq->db_id);
ivpu_hw_db_set(vdev, cmdq->db_id);
}
static int ivpu_preemption_buffers_create(struct ivpu_device *vdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment