Skip to content

Commit bfc87f9

Browse files
Krystian PradzynskiStanislaw Gruszka
authored andcommitted
accel/ivpu/40xx: Allow to change profiling frequency
Profiling freq is a debug firmware feature. It switches default clock to higher resolution for fine-grained and more accurate firmware task profiling. We already configure it during boot up of VPU4. Add debugfs knob and helpers per HW generation that allow to change it. For vpu37xx the implementation is empty as profiling frequency can only be changed on VPU4 or newer. Signed-off-by: Krystian Pradzynski <krystian.pradzynski@linux.intel.com> Reviewed-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Signed-off-by: Stanislaw Gruszka <stanislaw.gruszka@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231028155936.1183342-2-stanislaw.gruszka@linux.intel.com
1 parent 9d7c8c0 commit bfc87f9

File tree

5 files changed

+76
-0
lines changed

5 files changed

+76
-0
lines changed

drivers/accel/ivpu/ivpu_debugfs.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "ivpu_fw.h"
1515
#include "ivpu_fw_log.h"
1616
#include "ivpu_gem.h"
17+
#include "ivpu_hw.h"
1718
#include "ivpu_jsm_msg.h"
1819
#include "ivpu_pm.h"
1920

@@ -176,6 +177,30 @@ static const struct file_operations fw_log_fops = {
176177
.release = single_release,
177178
};
178179

180+
static ssize_t
181+
fw_profiling_freq_fops_write(struct file *file, const char __user *user_buf,
182+
size_t size, loff_t *pos)
183+
{
184+
struct ivpu_device *vdev = file->private_data;
185+
bool enable;
186+
int ret;
187+
188+
ret = kstrtobool_from_user(user_buf, size, &enable);
189+
if (ret < 0)
190+
return ret;
191+
192+
ivpu_hw_profiling_freq_drive(vdev, enable);
193+
ivpu_pm_schedule_recovery(vdev);
194+
195+
return size;
196+
}
197+
198+
static const struct file_operations fw_profiling_freq_fops = {
199+
.owner = THIS_MODULE,
200+
.open = simple_open,
201+
.write = fw_profiling_freq_fops_write,
202+
};
203+
179204
static ssize_t
180205
fw_trace_destination_mask_fops_write(struct file *file, const char __user *user_buf,
181206
size_t size, loff_t *pos)
@@ -319,4 +344,8 @@ void ivpu_debugfs_init(struct ivpu_device *vdev)
319344

320345
debugfs_create_file("reset_engine", 0200, debugfs_root, vdev,
321346
&ivpu_reset_engine_fops);
347+
348+
if (ivpu_hw_gen(vdev) >= IVPU_HW_40XX)
349+
debugfs_create_file("fw_profiling_freq_drive", 0200,
350+
debugfs_root, vdev, &fw_profiling_freq_fops);
322351
}

drivers/accel/ivpu/ivpu_fw.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,13 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params
498498
boot_params->vpu_id = to_pci_dev(vdev->drm.dev)->bus->number;
499499
boot_params->frequency = ivpu_hw_reg_pll_freq_get(vdev);
500500

501+
/*
502+
* This param is a debug firmware feature. It switches default clock
503+
* to higher resolution one for fine-grained and more accurate firmware
504+
* task profiling.
505+
*/
506+
boot_params->perf_clk_frequency = ivpu_hw_profiling_freq_get(vdev);
507+
501508
/*
502509
* Uncached region of VPU address space, covers IPC buffers, job queues
503510
* and log buffers, programmable to L2$ Uncached by VPU MTRR

drivers/accel/ivpu/ivpu_hw.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct ivpu_hw_ops {
1717
int (*wait_for_idle)(struct ivpu_device *vdev);
1818
void (*wdt_disable)(struct ivpu_device *vdev);
1919
void (*diagnose_failure)(struct ivpu_device *vdev);
20+
u32 (*profiling_freq_get)(struct ivpu_device *vdev);
21+
void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
2022
u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
2123
u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
2224
u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
@@ -104,6 +106,16 @@ static inline void ivpu_hw_wdt_disable(struct ivpu_device *vdev)
104106
vdev->hw->ops->wdt_disable(vdev);
105107
};
106108

109+
static inline u32 ivpu_hw_profiling_freq_get(struct ivpu_device *vdev)
110+
{
111+
return vdev->hw->ops->profiling_freq_get(vdev);
112+
};
113+
114+
static inline void ivpu_hw_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
115+
{
116+
return vdev->hw->ops->profiling_freq_drive(vdev, enable);
117+
};
118+
107119
/* Register indirect accesses */
108120
static inline u32 ivpu_hw_reg_pll_freq_get(struct ivpu_device *vdev)
109121
{

drivers/accel/ivpu/ivpu_hw_37xx.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#define PLL_REF_CLK_FREQ (50 * 1000000)
3131
#define PLL_SIMULATION_FREQ (10 * 1000000)
32+
#define PLL_PROF_CLK_FREQ (38400 * 1000)
3233
#define PLL_DEFAULT_EPP_VALUE 0x80
3334

3435
#define TIM_SAFE_ENABLE 0xf1d0dead
@@ -769,6 +770,16 @@ static void ivpu_hw_37xx_wdt_disable(struct ivpu_device *vdev)
769770
REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
770771
}
771772

773+
static u32 ivpu_hw_37xx_profiling_freq_get(struct ivpu_device *vdev)
774+
{
775+
return PLL_PROF_CLK_FREQ;
776+
}
777+
778+
static void ivpu_hw_37xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
779+
{
780+
/* Profiling freq - is a debug feature. Unavailable on VPU 37XX. */
781+
}
782+
772783
static u32 ivpu_hw_37xx_pll_to_freq(u32 ratio, u32 config)
773784
{
774785
u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
@@ -1012,6 +1023,8 @@ const struct ivpu_hw_ops ivpu_hw_37xx_ops = {
10121023
.boot_fw = ivpu_hw_37xx_boot_fw,
10131024
.wdt_disable = ivpu_hw_37xx_wdt_disable,
10141025
.diagnose_failure = ivpu_hw_37xx_diagnose_failure,
1026+
.profiling_freq_get = ivpu_hw_37xx_profiling_freq_get,
1027+
.profiling_freq_drive = ivpu_hw_37xx_profiling_freq_drive,
10151028
.reg_pll_freq_get = ivpu_hw_37xx_reg_pll_freq_get,
10161029
.reg_telemetry_offset_get = ivpu_hw_37xx_reg_telemetry_offset_get,
10171030
.reg_telemetry_size_get = ivpu_hw_37xx_reg_telemetry_size_get,

drivers/accel/ivpu/ivpu_hw_40xx.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,19 @@ static void ivpu_hw_40xx_wdt_disable(struct ivpu_device *vdev)
931931
REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
932932
}
933933

934+
static u32 ivpu_hw_40xx_profiling_freq_get(struct ivpu_device *vdev)
935+
{
936+
return vdev->hw->pll.profiling_freq;
937+
}
938+
939+
static void ivpu_hw_40xx_profiling_freq_drive(struct ivpu_device *vdev, bool enable)
940+
{
941+
if (enable)
942+
vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_HIGH;
943+
else
944+
vdev->hw->pll.profiling_freq = PLL_PROFILING_FREQ_DEFAULT;
945+
}
946+
934947
/* Register indirect accesses */
935948
static u32 ivpu_hw_40xx_reg_pll_freq_get(struct ivpu_device *vdev)
936949
{
@@ -1182,6 +1195,8 @@ const struct ivpu_hw_ops ivpu_hw_40xx_ops = {
11821195
.boot_fw = ivpu_hw_40xx_boot_fw,
11831196
.wdt_disable = ivpu_hw_40xx_wdt_disable,
11841197
.diagnose_failure = ivpu_hw_40xx_diagnose_failure,
1198+
.profiling_freq_get = ivpu_hw_40xx_profiling_freq_get,
1199+
.profiling_freq_drive = ivpu_hw_40xx_profiling_freq_drive,
11851200
.reg_pll_freq_get = ivpu_hw_40xx_reg_pll_freq_get,
11861201
.reg_telemetry_offset_get = ivpu_hw_40xx_reg_telemetry_offset_get,
11871202
.reg_telemetry_size_get = ivpu_hw_40xx_reg_telemetry_size_get,

0 commit comments

Comments
 (0)