mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:24:31 +01:00
crypto: qat - enable power management debugfs for GEN6 devices
The QAT driver includes infrastructure to report power management (PM) information via debugfs. Extend this support to QAT GEN6 devices by exposing PM debug data through the `pm_status` file. This implementation reports the current PM state, power management hardware control and status registers (CSR), and per-domain power status specific to the QAT GEN6 architecture. The debug functionality is implemented in adf_gen6_pm_dbgfs.c and initialized as part of the enable_pm() function. Co-developed-by: Vijay Sundar Selvamani <vijay.sundar.selvamani@intel.com> Signed-off-by: Vijay Sundar Selvamani <vijay.sundar.selvamani@intel.com> Signed-off-by: George Abraham P <george.abraham.p@intel.com> Signed-off-by: Suman Kumar Chakraborty <suman.kumar.chakraborty@intel.com> Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
7c68005a46
commit
c963ff0ec4
5 changed files with 160 additions and 2 deletions
|
|
@ -67,7 +67,7 @@ Contact: qat-linux@intel.com
|
|||
Description: (RO) Read returns power management information specific to the
|
||||
QAT device.
|
||||
|
||||
This attribute is only available for qat_4xxx devices.
|
||||
This attribute is only available for qat_4xxx and qat_6xxx devices.
|
||||
|
||||
What: /sys/kernel/debug/qat_<device>_<BDF>/cnv_errors
|
||||
Date: January 2024
|
||||
|
|
|
|||
|
|
@ -763,7 +763,16 @@ static int adf_init_device(struct adf_accel_dev *accel_dev)
|
|||
|
||||
static int enable_pm(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
return adf_init_admin_pm(accel_dev, ADF_GEN6_PM_DEFAULT_IDLE_FILTER);
|
||||
int ret;
|
||||
|
||||
ret = adf_init_admin_pm(accel_dev, ADF_GEN6_PM_DEFAULT_IDLE_FILTER);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Initialize PM internal data */
|
||||
adf_gen6_init_dev_pm_data(accel_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dev_config(struct adf_accel_dev *accel_dev)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ intel_qat-$(CONFIG_DEBUG_FS) += adf_cnv_dbgfs.o \
|
|||
adf_fw_counters.o \
|
||||
adf_gen4_pm_debugfs.o \
|
||||
adf_gen4_tl.o \
|
||||
adf_gen6_pm_dbgfs.o \
|
||||
adf_heartbeat_dbgfs.o \
|
||||
adf_heartbeat.o \
|
||||
adf_pm_dbgfs.o \
|
||||
|
|
|
|||
|
|
@ -24,5 +24,29 @@ struct adf_accel_dev;
|
|||
|
||||
/* cpm_pm_status bitfields */
|
||||
#define ADF_GEN6_PM_INIT_STATE BIT(21)
|
||||
#define ADF_GEN6_PM_CPM_PM_STATE_MASK GENMASK(22, 20)
|
||||
|
||||
/* fusectl0 bitfields */
|
||||
#define ADF_GEN6_PM_ENABLE_PM_MASK BIT(21)
|
||||
#define ADF_GEN6_PM_ENABLE_PM_IDLE_MASK BIT(22)
|
||||
#define ADF_GEN6_PM_ENABLE_DEEP_PM_IDLE_MASK BIT(23)
|
||||
|
||||
/* cpm_pm_fw_init bitfields */
|
||||
#define ADF_GEN6_PM_IDLE_FILTER_MASK GENMASK(5, 3)
|
||||
#define ADF_GEN6_PM_IDLE_ENABLE_MASK BIT(2)
|
||||
|
||||
/* ssm_pm_enable bitfield */
|
||||
#define ADF_GEN6_PM_SSM_PM_ENABLE_MASK BIT(0)
|
||||
|
||||
/* ssm_pm_domain_status bitfield */
|
||||
#define ADF_GEN6_PM_DOMAIN_POWERED_UP_MASK BIT(0)
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void adf_gen6_init_dev_pm_data(struct adf_accel_dev *accel_dev);
|
||||
#else
|
||||
static inline void adf_gen6_init_dev_pm_data(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
#endif /* ADF_GEN6_PM_H */
|
||||
|
|
|
|||
124
drivers/crypto/intel/qat/qat_common/adf_gen6_pm_dbgfs.c
Normal file
124
drivers/crypto/intel/qat/qat_common/adf_gen6_pm_dbgfs.c
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright(c) 2025 Intel Corporation */
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "adf_admin.h"
|
||||
#include "adf_common_drv.h"
|
||||
#include "adf_gen6_pm.h"
|
||||
#include "adf_pm_dbgfs_utils.h"
|
||||
#include "icp_qat_fw_init_admin.h"
|
||||
|
||||
#define PM_INFO_REGSET_ENTRY(_reg_, _field_) \
|
||||
PM_INFO_REGSET_ENTRY_MASK(_reg_, _field_, ADF_GEN6_PM_##_field_##_MASK)
|
||||
|
||||
static struct pm_status_row pm_fuse_rows[] = {
|
||||
PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_PM),
|
||||
PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_PM_IDLE),
|
||||
PM_INFO_REGSET_ENTRY(fusectl0, ENABLE_DEEP_PM_IDLE),
|
||||
};
|
||||
|
||||
static struct pm_status_row pm_info_rows[] = {
|
||||
PM_INFO_REGSET_ENTRY(pm.status, CPM_PM_STATE),
|
||||
PM_INFO_REGSET_ENTRY(pm.fw_init, IDLE_ENABLE),
|
||||
PM_INFO_REGSET_ENTRY(pm.fw_init, IDLE_FILTER),
|
||||
};
|
||||
|
||||
static struct pm_status_row pm_ssm_rows[] = {
|
||||
PM_INFO_REGSET_ENTRY(ssm.pm_enable, SSM_PM_ENABLE),
|
||||
PM_INFO_REGSET_ENTRY(ssm.pm_domain_status, DOMAIN_POWERED_UP),
|
||||
};
|
||||
|
||||
static struct pm_status_row pm_csrs_rows[] = {
|
||||
PM_INFO_REGSET_ENTRY32(pm.fw_init, CPM_PM_FW_INIT),
|
||||
PM_INFO_REGSET_ENTRY32(pm.status, CPM_PM_STATUS),
|
||||
};
|
||||
|
||||
static_assert(sizeof(struct icp_qat_fw_init_admin_pm_info) < PAGE_SIZE);
|
||||
|
||||
static ssize_t adf_gen6_print_pm_status(struct adf_accel_dev *accel_dev,
|
||||
char __user *buf, size_t count,
|
||||
loff_t *pos)
|
||||
{
|
||||
void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
|
||||
struct icp_qat_fw_init_admin_pm_info *pm_info;
|
||||
dma_addr_t p_state_addr;
|
||||
u32 *pm_info_regs;
|
||||
size_t len = 0;
|
||||
char *pm_kv;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
pm_info = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!pm_info)
|
||||
return -ENOMEM;
|
||||
|
||||
pm_kv = kzalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!pm_kv) {
|
||||
kfree(pm_info);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
p_state_addr = dma_map_single(&GET_DEV(accel_dev), pm_info, PAGE_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
ret = dma_mapping_error(&GET_DEV(accel_dev), p_state_addr);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
/* Query power management information from QAT FW */
|
||||
ret = adf_get_pm_info(accel_dev, p_state_addr, PAGE_SIZE);
|
||||
dma_unmap_single(&GET_DEV(accel_dev), p_state_addr, PAGE_SIZE,
|
||||
DMA_FROM_DEVICE);
|
||||
if (ret)
|
||||
goto out_free;
|
||||
|
||||
pm_info_regs = (u32 *)pm_info;
|
||||
|
||||
/* Fuse control register */
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len,
|
||||
"----------- PM Fuse info ---------\n");
|
||||
len += adf_pm_scnprint_table_lower_keys(&pm_kv[len], pm_fuse_rows,
|
||||
pm_info_regs, PAGE_SIZE - len,
|
||||
ARRAY_SIZE(pm_fuse_rows));
|
||||
|
||||
/* Power management */
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len,
|
||||
"----------- PM Info --------------\n");
|
||||
|
||||
len += adf_pm_scnprint_table_lower_keys(&pm_kv[len], pm_info_rows,
|
||||
pm_info_regs, PAGE_SIZE - len,
|
||||
ARRAY_SIZE(pm_info_rows));
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len, "pm_mode: ACTIVE\n");
|
||||
|
||||
/* Shared Slice Module */
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len,
|
||||
"----------- SSM_PM Info ----------\n");
|
||||
len += adf_pm_scnprint_table_lower_keys(&pm_kv[len], pm_ssm_rows,
|
||||
pm_info_regs, PAGE_SIZE - len,
|
||||
ARRAY_SIZE(pm_ssm_rows));
|
||||
|
||||
/* Control status register content */
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len,
|
||||
"----------- HW PM CSRs -----------\n");
|
||||
len += adf_pm_scnprint_table_upper_keys(&pm_kv[len], pm_csrs_rows,
|
||||
pm_info_regs, PAGE_SIZE - len,
|
||||
ARRAY_SIZE(pm_csrs_rows));
|
||||
|
||||
val = ADF_CSR_RD(pmisc, ADF_GEN6_PM_INTERRUPT);
|
||||
len += scnprintf(&pm_kv[len], PAGE_SIZE - len, "CPM_PM_INTERRUPT: %#x\n", val);
|
||||
ret = simple_read_from_buffer(buf, count, pos, pm_kv, len);
|
||||
|
||||
out_free:
|
||||
kfree(pm_info);
|
||||
kfree(pm_kv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void adf_gen6_init_dev_pm_data(struct adf_accel_dev *accel_dev)
|
||||
{
|
||||
accel_dev->power_management.print_pm_status = adf_gen6_print_pm_status;
|
||||
accel_dev->power_management.present = true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(adf_gen6_init_dev_pm_data);
|
||||
Loading…
Add table
Add a link
Reference in a new issue