crypto: hisilicon - check the sva module status while enabling or disabling address prefetch

After enabling address prefetch, check the sva module status. If all
previous prefetch requests from the sva module are not completed, then
disable the address prefetch to ensure normal execution of new task
operations. After disabling address prefetch, check if all requests
from the sva module have been completed.

Fixes: a5c164b195 ("crypto: hisilicon/qm - support address prefetching")
Signed-off-by: Weili Qian <qianweili@huawei.com>
Signed-off-by: Chenghai Huang <huangchenghai2@huawei.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Weili Qian
2025-08-21 09:38:06 +08:00
committed by Herbert Xu
parent 0dcd21443d
commit 1f9128f121
3 changed files with 177 additions and 39 deletions

View File

@@ -93,6 +93,16 @@
#define SEC_PREFETCH_ENABLE (~(BIT(0) | BIT(1) | BIT(11)))
#define SEC_PREFETCH_DISABLE BIT(1)
#define SEC_SVA_DISABLE_READY (BIT(7) | BIT(11))
#define SEC_SVA_PREFETCH_INFO 0x301ED4
#define SEC_SVA_STALL_NUM GENMASK(23, 8)
#define SEC_SVA_PREFETCH_NUM GENMASK(2, 0)
#define SEC_WAIT_SVA_READY 500000
#define SEC_READ_SVA_STATUS_TIMES 3
#define SEC_WAIT_US_MIN 10
#define SEC_WAIT_US_MAX 20
#define SEC_WAIT_QP_US_MIN 1000
#define SEC_WAIT_QP_US_MAX 2000
#define SEC_MAX_WAIT_TIMES 2000
#define SEC_DELAY_10_US 10
#define SEC_POLL_TIMEOUT_US 1000
@@ -464,6 +474,33 @@ static void sec_set_endian(struct hisi_qm *qm)
writel_relaxed(reg, qm->io_base + SEC_CONTROL_REG);
}
static int sec_wait_sva_ready(struct hisi_qm *qm, __u32 offset, __u32 mask)
{
u32 val, try_times = 0;
u8 count = 0;
/*
* Read the register value every 10-20us. If the value is 0 for three
* consecutive times, the SVA module is ready.
*/
do {
val = readl(qm->io_base + offset);
if (val & mask)
count = 0;
else if (++count == SEC_READ_SVA_STATUS_TIMES)
break;
usleep_range(SEC_WAIT_US_MIN, SEC_WAIT_US_MAX);
} while (++try_times < SEC_WAIT_SVA_READY);
if (try_times == SEC_WAIT_SVA_READY) {
pci_err(qm->pdev, "failed to wait sva prefetch ready\n");
return -ETIMEDOUT;
}
return 0;
}
static void sec_close_sva_prefetch(struct hisi_qm *qm)
{
u32 val;
@@ -481,6 +518,8 @@ static void sec_close_sva_prefetch(struct hisi_qm *qm)
SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US);
if (ret)
pci_err(qm->pdev, "failed to close sva prefetch\n");
(void)sec_wait_sva_ready(qm, SEC_SVA_PREFETCH_INFO, SEC_SVA_STALL_NUM);
}
static void sec_open_sva_prefetch(struct hisi_qm *qm)
@@ -499,8 +538,15 @@ static void sec_open_sva_prefetch(struct hisi_qm *qm)
ret = readl_relaxed_poll_timeout(qm->io_base + SEC_PREFETCH_CFG,
val, !(val & SEC_PREFETCH_DISABLE),
SEC_DELAY_10_US, SEC_POLL_TIMEOUT_US);
if (ret)
if (ret) {
pci_err(qm->pdev, "failed to open sva prefetch\n");
sec_close_sva_prefetch(qm);
return;
}
ret = sec_wait_sva_ready(qm, SEC_SVA_TRANS, SEC_SVA_PREFETCH_NUM);
if (ret)
sec_close_sva_prefetch(qm);
}
static void sec_engine_sva_config(struct hisi_qm *qm)