|
Torsten Duwe |
2dc170 |
From e5745f34113b758b45d134dec04a7df94dc67131 Mon Sep 17 00:00:00 2001
|
|
Torsten Duwe |
2dc170 |
From: Wojciech Ziemba <wojciech.ziemba@intel.com>
|
|
Torsten Duwe |
2dc170 |
Date: Thu, 10 Feb 2022 13:38:27 +0000
|
|
Torsten Duwe |
2dc170 |
Subject: [PATCH] crypto: qat - enable power management for QAT GEN4
|
|
Torsten Duwe |
2dc170 |
Git-commit: e5745f34113b758b45d134dec04a7df94dc67131
|
|
Torsten Duwe |
2dc170 |
Patch-mainline: v5.18-rc1
|
|
Torsten Duwe |
2dc170 |
References: jsc#PED-1073
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
Add support for HW QAT Power Management (PM) feature.
|
|
Torsten Duwe |
2dc170 |
This feature is enabled at init time (1) by sending an admin message to
|
|
Torsten Duwe |
2dc170 |
the firmware, targeting the admin AE, that sets the idle time before
|
|
Torsten Duwe |
2dc170 |
the device changes state and (2) by unmasking the PM source of interrupt
|
|
Torsten Duwe |
2dc170 |
in ERRMSK2.
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
The interrupt handler is extended to handle a PM interrupt which
|
|
Torsten Duwe |
2dc170 |
is triggered by HW when a PM transition occurs. In this case, the
|
|
Torsten Duwe |
2dc170 |
driver responds acknowledging the transaction using the HOST_MSG
|
|
Torsten Duwe |
2dc170 |
mailbox.
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
Signed-off-by: Wojciech Ziemba <wojciech.ziemba@intel.com>
|
|
Torsten Duwe |
2dc170 |
Co-developed-by: Marcinx Malinowski <marcinx.malinowski@intel.com>
|
|
Torsten Duwe |
2dc170 |
Signed-off-by: Marcinx Malinowski <marcinx.malinowski@intel.com>
|
|
Torsten Duwe |
2dc170 |
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
|
|
Torsten Duwe |
2dc170 |
Reviewed-by: Marco Chiappero <marco.chiappero@intel.com>
|
|
Torsten Duwe |
2dc170 |
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
|
|
Torsten Duwe |
2dc170 |
Signed-off-by: Torsten Duwe <duwe@suse.de>
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
---
|
|
Torsten Duwe |
2dc170 |
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 15 +-
|
|
Torsten Duwe |
2dc170 |
.../crypto/qat/qat_4xxx/adf_4xxx_hw_data.h | 10 --
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/Makefile | 1 +
|
|
Torsten Duwe |
2dc170 |
.../crypto/qat/qat_common/adf_accel_devices.h | 2 +
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/adf_admin.c | 37 +++++
|
|
Torsten Duwe |
2dc170 |
.../crypto/qat/qat_common/adf_common_drv.h | 1 +
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/adf_gen4_pm.c | 137 ++++++++++++++++++
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/adf_gen4_pm.h | 44 ++++++
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/adf_init.c | 6 +
|
|
Torsten Duwe |
2dc170 |
drivers/crypto/qat/qat_common/adf_isr.c | 14 ++
|
|
Torsten Duwe |
2dc170 |
.../qat/qat_common/icp_qat_fw_init_admin.h | 1 +
|
|
Torsten Duwe |
2dc170 |
11 files changed, 252 insertions(+), 16 deletions(-)
|
|
Torsten Duwe |
2dc170 |
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pm.c
|
|
Torsten Duwe |
2dc170 |
create mode 100644 drivers/crypto/qat/qat_common/adf_gen4_pm.h
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
|
|
Torsten Duwe |
2dc170 |
index 69fb271c85dd6..fb5970a684844 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
|
|
Torsten Duwe |
2dc170 |
@@ -6,6 +6,7 @@
|
|
Torsten Duwe |
2dc170 |
#include <adf_common_drv.h>
|
|
Torsten Duwe |
2dc170 |
#include <adf_gen4_hw_data.h>
|
|
Torsten Duwe |
2dc170 |
#include <adf_gen4_pfvf.h>
|
|
Torsten Duwe |
2dc170 |
+#include <adf_gen4_pm.h>
|
|
Torsten Duwe |
2dc170 |
#include "adf_4xxx_hw_data.h"
|
|
Torsten Duwe |
2dc170 |
#include "icp_qat_hw.h"
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
@@ -257,18 +258,18 @@ static int adf_init_device(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
/* Temporarily mask PM interrupt */
|
|
Torsten Duwe |
2dc170 |
csr = ADF_CSR_RD(addr, ADF_GEN4_ERRMSK2);
|
|
Torsten Duwe |
2dc170 |
- csr |= ADF_4XXX_PM_SOU;
|
|
Torsten Duwe |
2dc170 |
+ csr |= ADF_GEN4_PM_SOU;
|
|
Torsten Duwe |
2dc170 |
ADF_CSR_WR(addr, ADF_GEN4_ERRMSK2, csr);
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
/* Set DRV_ACTIVE bit to power up the device */
|
|
Torsten Duwe |
2dc170 |
- ADF_CSR_WR(addr, ADF_4XXX_PM_INTERRUPT, ADF_4XXX_PM_DRV_ACTIVE);
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(addr, ADF_GEN4_PM_INTERRUPT, ADF_GEN4_PM_DRV_ACTIVE);
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
/* Poll status register to make sure the device is powered up */
|
|
Torsten Duwe |
2dc170 |
ret = read_poll_timeout(ADF_CSR_RD, status,
|
|
Torsten Duwe |
2dc170 |
- status & ADF_4XXX_PM_INIT_STATE,
|
|
Torsten Duwe |
2dc170 |
- ADF_4XXX_PM_POLL_DELAY_US,
|
|
Torsten Duwe |
2dc170 |
- ADF_4XXX_PM_POLL_TIMEOUT_US, true, addr,
|
|
Torsten Duwe |
2dc170 |
- ADF_4XXX_PM_STATUS);
|
|
Torsten Duwe |
2dc170 |
+ status & ADF_GEN4_PM_INIT_STATE,
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_POLL_DELAY_US,
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_POLL_TIMEOUT_US, true, addr,
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_STATUS);
|
|
Torsten Duwe |
2dc170 |
if (ret)
|
|
Torsten Duwe |
2dc170 |
dev_err(&GET_DEV(accel_dev), "Failed to power up the device\n");
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
@@ -354,6 +355,8 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
|
|
Torsten Duwe |
2dc170 |
hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer;
|
|
Torsten Duwe |
2dc170 |
hw_data->disable_iov = adf_disable_sriov;
|
|
Torsten Duwe |
2dc170 |
hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;
|
|
Torsten Duwe |
2dc170 |
+ hw_data->enable_pm = adf_gen4_enable_pm;
|
|
Torsten Duwe |
2dc170 |
+ hw_data->handle_pm_interrupt = adf_gen4_handle_pm_interrupt;
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
adf_gen4_init_hw_csr_ops(&hw_data->csr_ops);
|
|
Torsten Duwe |
2dc170 |
adf_gen4_init_pf_pfvf_ops(&hw_data->pfvf_ops);
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
|
|
Torsten Duwe |
2dc170 |
index 857b93a3c032d..1034752845ca2 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.h
|
|
Torsten Duwe |
2dc170 |
@@ -49,16 +49,6 @@
|
|
Torsten Duwe |
2dc170 |
#define ADF_4XXX_ADMINMSGLR_OFFSET (0x500578)
|
|
Torsten Duwe |
2dc170 |
#define ADF_4XXX_MAILBOX_BASE_OFFSET (0x600970)
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
-/* Power management */
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_POLL_DELAY_US 20
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_POLL_TIMEOUT_US USEC_PER_SEC
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_STATUS (0x50A00C)
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_INTERRUPT (0x50A028)
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_DRV_ACTIVE BIT(20)
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_INIT_STATE BIT(21)
|
|
Torsten Duwe |
2dc170 |
-/* Power management source in ERRSOU2 and ERRMSK2 */
|
|
Torsten Duwe |
2dc170 |
-#define ADF_4XXX_PM_SOU BIT(18)
|
|
Torsten Duwe |
2dc170 |
-
|
|
Torsten Duwe |
2dc170 |
/* Firmware Binaries */
|
|
Torsten Duwe |
2dc170 |
#define ADF_4XXX_FW "qat_4xxx.bin"
|
|
Torsten Duwe |
2dc170 |
#define ADF_4XXX_MMP "qat_4xxx_mmp.bin"
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
|
|
Torsten Duwe |
2dc170 |
index 7e191a42a5c7e..f25a6c8edfc73 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/Makefile
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/Makefile
|
|
Torsten Duwe |
2dc170 |
@@ -12,6 +12,7 @@ intel_qat-objs := adf_cfg.o \
|
|
Torsten Duwe |
2dc170 |
adf_hw_arbiter.o \
|
|
Torsten Duwe |
2dc170 |
adf_gen2_hw_data.o \
|
|
Torsten Duwe |
2dc170 |
adf_gen4_hw_data.o \
|
|
Torsten Duwe |
2dc170 |
+ adf_gen4_pm.o \
|
|
Torsten Duwe |
2dc170 |
qat_crypto.o \
|
|
Torsten Duwe |
2dc170 |
qat_algs.o \
|
|
Torsten Duwe |
2dc170 |
qat_asym_algs.o \
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
2dc170 |
index 2d4cd7c7cf33b..a03c6cf723312 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
|
|
Torsten Duwe |
2dc170 |
@@ -184,6 +184,8 @@ struct adf_hw_device_data {
|
|
Torsten Duwe |
2dc170 |
void (*exit_arb)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
const u32 *(*get_arb_mapping)(void);
|
|
Torsten Duwe |
2dc170 |
int (*init_device)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ int (*enable_pm)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ bool (*handle_pm_interrupt)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
void (*disable_iov)(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
void (*configure_iov_threads)(struct adf_accel_dev *accel_dev,
|
|
Torsten Duwe |
2dc170 |
bool enable);
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_admin.c b/drivers/crypto/qat/qat_common/adf_admin.c
|
|
Torsten Duwe |
2dc170 |
index 498eb6f690e37..3b6184c350811 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/adf_admin.c
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_admin.c
|
|
Torsten Duwe |
2dc170 |
@@ -251,6 +251,43 @@ int adf_send_admin_init(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
}
|
|
Torsten Duwe |
2dc170 |
EXPORT_SYMBOL_GPL(adf_send_admin_init);
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
+/**
|
|
Torsten Duwe |
2dc170 |
+ * adf_init_admin_pm() - Function sends PM init message to FW
|
|
Torsten Duwe |
2dc170 |
+ * @accel_dev: Pointer to acceleration device.
|
|
Torsten Duwe |
2dc170 |
+ * @idle_delay: QAT HW idle time before power gating is initiated.
|
|
Torsten Duwe |
2dc170 |
+ * 000 - 64us
|
|
Torsten Duwe |
2dc170 |
+ * 001 - 128us
|
|
Torsten Duwe |
2dc170 |
+ * 010 - 256us
|
|
Torsten Duwe |
2dc170 |
+ * 011 - 512us
|
|
Torsten Duwe |
2dc170 |
+ * 100 - 1ms
|
|
Torsten Duwe |
2dc170 |
+ * 101 - 2ms
|
|
Torsten Duwe |
2dc170 |
+ * 110 - 4ms
|
|
Torsten Duwe |
2dc170 |
+ * 111 - 8ms
|
|
Torsten Duwe |
2dc170 |
+ *
|
|
Torsten Duwe |
2dc170 |
+ * Function sends to the FW the admin init message for the PM state
|
|
Torsten Duwe |
2dc170 |
+ * configuration.
|
|
Torsten Duwe |
2dc170 |
+ *
|
|
Torsten Duwe |
2dc170 |
+ * Return: 0 on success, error code otherwise.
|
|
Torsten Duwe |
2dc170 |
+ */
|
|
Torsten Duwe |
2dc170 |
+int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
|
|
Torsten Duwe |
2dc170 |
+ struct icp_qat_fw_init_admin_resp resp = {0};
|
|
Torsten Duwe |
2dc170 |
+ struct icp_qat_fw_init_admin_req req = {0};
|
|
Torsten Duwe |
2dc170 |
+ u32 ae_mask = hw_data->admin_ae_mask;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ if (!accel_dev->admin) {
|
|
Torsten Duwe |
2dc170 |
+ dev_err(&GET_DEV(accel_dev), "adf_admin is not available\n");
|
|
Torsten Duwe |
2dc170 |
+ return -EFAULT;
|
|
Torsten Duwe |
2dc170 |
+ }
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ req.cmd_id = ICP_QAT_FW_PM_STATE_CONFIG;
|
|
Torsten Duwe |
2dc170 |
+ req.idle_filter = idle_delay;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ return adf_send_admin(accel_dev, &req, &resp, ae_mask);
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+EXPORT_SYMBOL_GPL(adf_init_admin_pm);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
{
|
|
Torsten Duwe |
2dc170 |
struct adf_admin_comms *admin;
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_common_drv.h b/drivers/crypto/qat/qat_common/adf_common_drv.h
|
|
Torsten Duwe |
2dc170 |
index 0775491768797..e8c9b77c0d66b 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/adf_common_drv.h
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_common_drv.h
|
|
Torsten Duwe |
2dc170 |
@@ -102,6 +102,7 @@ void adf_exit_aer(void);
|
|
Torsten Duwe |
2dc170 |
int adf_init_admin_comms(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
void adf_exit_admin_comms(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
int adf_send_admin_init(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
+int adf_init_admin_pm(struct adf_accel_dev *accel_dev, u32 idle_delay);
|
|
Torsten Duwe |
2dc170 |
int adf_init_arb(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
void adf_exit_arb(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
void adf_update_ring_arb(struct adf_etr_ring_data *ring);
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pm.c b/drivers/crypto/qat/qat_common/adf_gen4_pm.c
|
|
Torsten Duwe |
2dc170 |
new file mode 100644
|
|
Torsten Duwe |
2dc170 |
index 0000000000000..7037c0892a8a2
|
|
Torsten Duwe |
2dc170 |
--- /dev/null
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pm.c
|
|
Torsten Duwe |
2dc170 |
@@ -0,0 +1,137 @@
|
|
Torsten Duwe |
2dc170 |
+// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
|
|
Torsten Duwe |
2dc170 |
+/* Copyright(c) 2022 Intel Corporation */
|
|
Torsten Duwe |
2dc170 |
+#include <linux/bitfield.h>
|
|
Torsten Duwe |
2dc170 |
+#include <linux/iopoll.h>
|
|
Torsten Duwe |
2dc170 |
+#include "adf_accel_devices.h"
|
|
Torsten Duwe |
2dc170 |
+#include "adf_common_drv.h"
|
|
Torsten Duwe |
2dc170 |
+#include "adf_gen4_pm.h"
|
|
Torsten Duwe |
2dc170 |
+#include "adf_cfg_strings.h"
|
|
Torsten Duwe |
2dc170 |
+#include "icp_qat_fw_init_admin.h"
|
|
Torsten Duwe |
2dc170 |
+#include "adf_gen4_hw_data.h"
|
|
Torsten Duwe |
2dc170 |
+#include "adf_cfg.h"
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+enum qat_pm_host_msg {
|
|
Torsten Duwe |
2dc170 |
+ PM_NO_CHANGE = 0,
|
|
Torsten Duwe |
2dc170 |
+ PM_SET_MIN,
|
|
Torsten Duwe |
2dc170 |
+};
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+struct adf_gen4_pm_data {
|
|
Torsten Duwe |
2dc170 |
+ struct work_struct pm_irq_work;
|
|
Torsten Duwe |
2dc170 |
+ struct adf_accel_dev *accel_dev;
|
|
Torsten Duwe |
2dc170 |
+ u32 pm_int_sts;
|
|
Torsten Duwe |
2dc170 |
+};
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+static int send_host_msg(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ u32 msg;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ msg = ADF_CSR_RD(pmisc, ADF_GEN4_PM_HOST_MSG);
|
|
Torsten Duwe |
2dc170 |
+ if (msg & ADF_GEN4_PM_MSG_PENDING)
|
|
Torsten Duwe |
2dc170 |
+ return -EBUSY;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Send HOST_MSG */
|
|
Torsten Duwe |
2dc170 |
+ msg = FIELD_PREP(ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK, PM_SET_MIN);
|
|
Torsten Duwe |
2dc170 |
+ msg |= ADF_GEN4_PM_MSG_PENDING;
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_HOST_MSG, msg);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Poll status register to make sure the HOST_MSG has been processed */
|
|
Torsten Duwe |
2dc170 |
+ return read_poll_timeout(ADF_CSR_RD, msg,
|
|
Torsten Duwe |
2dc170 |
+ !(msg & ADF_GEN4_PM_MSG_PENDING),
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_MSG_POLL_DELAY_US,
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_POLL_TIMEOUT_US, true, pmisc,
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_HOST_MSG);
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+static void pm_bh_handler(struct work_struct *work)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ struct adf_gen4_pm_data *pm_data =
|
|
Torsten Duwe |
2dc170 |
+ container_of(work, struct adf_gen4_pm_data, pm_irq_work);
|
|
Torsten Duwe |
2dc170 |
+ struct adf_accel_dev *accel_dev = pm_data->accel_dev;
|
|
Torsten Duwe |
2dc170 |
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ u32 pm_int_sts = pm_data->pm_int_sts;
|
|
Torsten Duwe |
2dc170 |
+ u32 val;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* PM Idle interrupt */
|
|
Torsten Duwe |
2dc170 |
+ if (pm_int_sts & ADF_GEN4_PM_IDLE_STS) {
|
|
Torsten Duwe |
2dc170 |
+ /* Issue host message to FW */
|
|
Torsten Duwe |
2dc170 |
+ if (send_host_msg(accel_dev))
|
|
Torsten Duwe |
2dc170 |
+ dev_warn_ratelimited(&GET_DEV(accel_dev),
|
|
Torsten Duwe |
2dc170 |
+ "Failed to send host msg to FW\n");
|
|
Torsten Duwe |
2dc170 |
+ }
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Clear interrupt status */
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, pm_int_sts);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Reenable PM interrupt */
|
|
Torsten Duwe |
2dc170 |
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
|
|
Torsten Duwe |
2dc170 |
+ val &= ~ADF_GEN4_PM_SOU;
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ kfree(pm_data);
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ struct adf_gen4_pm_data *pm_data = NULL;
|
|
Torsten Duwe |
2dc170 |
+ u32 errsou2;
|
|
Torsten Duwe |
2dc170 |
+ u32 errmsk2;
|
|
Torsten Duwe |
2dc170 |
+ u32 val;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Only handle the interrupt triggered by PM */
|
|
Torsten Duwe |
2dc170 |
+ errmsk2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
|
|
Torsten Duwe |
2dc170 |
+ if (errmsk2 & ADF_GEN4_PM_SOU)
|
|
Torsten Duwe |
2dc170 |
+ return false;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ errsou2 = ADF_CSR_RD(pmisc, ADF_GEN4_ERRSOU2);
|
|
Torsten Duwe |
2dc170 |
+ if (!(errsou2 & ADF_GEN4_PM_SOU))
|
|
Torsten Duwe |
2dc170 |
+ return false;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Disable interrupt */
|
|
Torsten Duwe |
2dc170 |
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
|
|
Torsten Duwe |
2dc170 |
+ val |= ADF_GEN4_PM_SOU;
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ pm_data = kzalloc(sizeof(*pm_data), GFP_ATOMIC);
|
|
Torsten Duwe |
2dc170 |
+ if (!pm_data)
|
|
Torsten Duwe |
2dc170 |
+ return false;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ pm_data->pm_int_sts = val;
|
|
Torsten Duwe |
2dc170 |
+ pm_data->accel_dev = accel_dev;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ INIT_WORK(&pm_data->pm_irq_work, pm_bh_handler);
|
|
Torsten Duwe |
2dc170 |
+ adf_misc_wq_queue_work(&pm_data->pm_irq_work);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ return true;
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+EXPORT_SYMBOL_GPL(adf_gen4_handle_pm_interrupt);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ void __iomem *pmisc = adf_get_pmisc_base(accel_dev);
|
|
Torsten Duwe |
2dc170 |
+ int ret;
|
|
Torsten Duwe |
2dc170 |
+ u32 val;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ ret = adf_init_admin_pm(accel_dev, ADF_GEN4_PM_DEFAULT_IDLE_FILTER);
|
|
Torsten Duwe |
2dc170 |
+ if (ret)
|
|
Torsten Duwe |
2dc170 |
+ return ret;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Enable default PM interrupts: IDLE, THROTTLE */
|
|
Torsten Duwe |
2dc170 |
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT);
|
|
Torsten Duwe |
2dc170 |
+ val |= ADF_GEN4_PM_INT_EN_DEFAULT;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Clear interrupt status */
|
|
Torsten Duwe |
2dc170 |
+ val |= ADF_GEN4_PM_INT_STS_MASK;
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_PM_INTERRUPT, val);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ /* Unmask PM Interrupt */
|
|
Torsten Duwe |
2dc170 |
+ val = ADF_CSR_RD(pmisc, ADF_GEN4_ERRMSK2);
|
|
Torsten Duwe |
2dc170 |
+ val &= ~ADF_GEN4_PM_SOU;
|
|
Torsten Duwe |
2dc170 |
+ ADF_CSR_WR(pmisc, ADF_GEN4_ERRMSK2, val);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ return 0;
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+EXPORT_SYMBOL_GPL(adf_gen4_enable_pm);
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_pm.h b/drivers/crypto/qat/qat_common/adf_gen4_pm.h
|
|
Torsten Duwe |
2dc170 |
new file mode 100644
|
|
Torsten Duwe |
2dc170 |
index 0000000000000..f8f8a9ee29e5b
|
|
Torsten Duwe |
2dc170 |
--- /dev/null
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_gen4_pm.h
|
|
Torsten Duwe |
2dc170 |
@@ -0,0 +1,44 @@
|
|
Torsten Duwe |
2dc170 |
+/* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) */
|
|
Torsten Duwe |
2dc170 |
+/* Copyright(c) 2022 Intel Corporation */
|
|
Torsten Duwe |
2dc170 |
+#ifndef ADF_GEN4_PM_H
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_H
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#include "adf_accel_devices.h"
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+/* Power management registers */
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_HOST_MSG (0x50A01C)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+/* Power management */
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_POLL_DELAY_US 20
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_POLL_TIMEOUT_US USEC_PER_SEC
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_MSG_POLL_DELAY_US (10 * USEC_PER_MSEC)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_STATUS (0x50A00C)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_INTERRUPT (0x50A028)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+/* Power management source in ERRSOU2 and ERRMSK2 */
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_SOU BIT(18)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_IDLE_INT_EN BIT(18)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_THROTTLE_INT_EN BIT(19)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_DRV_ACTIVE BIT(20)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_INIT_STATE BIT(21)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_INT_EN_DEFAULT (ADF_GEN4_PM_IDLE_INT_EN | \
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_THROTTLE_INT_EN)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_THR_STS BIT(0)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_IDLE_STS BIT(1)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_FW_INT_STS BIT(2)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_INT_STS_MASK (ADF_GEN4_PM_THR_STS | \
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_IDLE_STS | \
|
|
Torsten Duwe |
2dc170 |
+ ADF_GEN4_PM_FW_INT_STS)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_MSG_PENDING BIT(0)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK GENMASK(28, 1)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x0)
|
|
Torsten Duwe |
2dc170 |
+#define ADF_GEN4_PM_MAX_IDLE_FILTER (0x7)
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
+bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev);
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+#endif
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
|
|
Torsten Duwe |
2dc170 |
index 2edc63c6b6caa..c2c718f1b4895 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/adf_init.c
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_init.c
|
|
Torsten Duwe |
2dc170 |
@@ -181,6 +181,12 @@ int adf_dev_start(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
if (hw_data->set_ssm_wdtimer)
|
|
Torsten Duwe |
2dc170 |
hw_data->set_ssm_wdtimer(accel_dev);
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
+ /* Enable Power Management */
|
|
Torsten Duwe |
2dc170 |
+ if (hw_data->enable_pm && hw_data->enable_pm(accel_dev)) {
|
|
Torsten Duwe |
2dc170 |
+ dev_err(&GET_DEV(accel_dev), "Failed to configure Power Management\n");
|
|
Torsten Duwe |
2dc170 |
+ return -EFAULT;
|
|
Torsten Duwe |
2dc170 |
+ }
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
list_for_each(list_itr, &service_table) {
|
|
Torsten Duwe |
2dc170 |
service = list_entry(list_itr, struct service_hndl, list);
|
|
Torsten Duwe |
2dc170 |
if (service->event_hld(accel_dev, ADF_EVENT_START)) {
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
2dc170 |
index 803b89ba9670c..a35149f8bf1ee 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/adf_isr.c
|
|
Torsten Duwe |
2dc170 |
@@ -124,6 +124,17 @@ static bool adf_handle_vf2pf_int(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
}
|
|
Torsten Duwe |
2dc170 |
#endif /* CONFIG_PCI_IOV */
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
+static bool adf_handle_pm_int(struct adf_accel_dev *accel_dev)
|
|
Torsten Duwe |
2dc170 |
+{
|
|
Torsten Duwe |
2dc170 |
+ struct adf_hw_device_data *hw_data = accel_dev->hw_device;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ if (hw_data->handle_pm_interrupt &&
|
|
Torsten Duwe |
2dc170 |
+ hw_data->handle_pm_interrupt(accel_dev))
|
|
Torsten Duwe |
2dc170 |
+ return true;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
+ return false;
|
|
Torsten Duwe |
2dc170 |
+}
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
|
|
Torsten Duwe |
2dc170 |
{
|
|
Torsten Duwe |
2dc170 |
struct adf_accel_dev *accel_dev = dev_ptr;
|
|
Torsten Duwe |
2dc170 |
@@ -134,6 +145,9 @@ static irqreturn_t adf_msix_isr_ae(int irq, void *dev_ptr)
|
|
Torsten Duwe |
2dc170 |
return IRQ_HANDLED;
|
|
Torsten Duwe |
2dc170 |
#endif /* CONFIG_PCI_IOV */
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
+ if (adf_handle_pm_int(accel_dev))
|
|
Torsten Duwe |
2dc170 |
+ return IRQ_HANDLED;
|
|
Torsten Duwe |
2dc170 |
+
|
|
Torsten Duwe |
2dc170 |
dev_dbg(&GET_DEV(accel_dev), "qat_dev%d spurious AE interrupt\n",
|
|
Torsten Duwe |
2dc170 |
accel_dev->accel_id);
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
diff --git a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
|
|
Torsten Duwe |
2dc170 |
index afe59a7684ac5..56cb827f93ea3 100644
|
|
Torsten Duwe |
2dc170 |
--- a/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
|
|
Torsten Duwe |
2dc170 |
+++ b/drivers/crypto/qat/qat_common/icp_qat_fw_init_admin.h
|
|
Torsten Duwe |
2dc170 |
@@ -16,6 +16,7 @@ enum icp_qat_fw_init_admin_cmd_id {
|
|
Torsten Duwe |
2dc170 |
ICP_QAT_FW_HEARTBEAT_SYNC = 7,
|
|
Torsten Duwe |
2dc170 |
ICP_QAT_FW_HEARTBEAT_GET = 8,
|
|
Torsten Duwe |
2dc170 |
ICP_QAT_FW_COMP_CAPABILITY_GET = 9,
|
|
Torsten Duwe |
2dc170 |
+ ICP_QAT_FW_PM_STATE_CONFIG = 128,
|
|
Torsten Duwe |
2dc170 |
};
|
|
Torsten Duwe |
2dc170 |
|
|
Torsten Duwe |
2dc170 |
enum icp_qat_fw_init_admin_resp_status {
|
|
Torsten Duwe |
2dc170 |
--
|
|
Torsten Duwe |
2dc170 |
2.35.3
|
|
Torsten Duwe |
2dc170 |
|