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

@@ -95,10 +95,16 @@
#define HZIP_PREFETCH_ENABLE (~(BIT(26) | BIT(17) | BIT(0)))
#define HZIP_SVA_PREFETCH_DISABLE BIT(26)
#define HZIP_SVA_DISABLE_READY (BIT(26) | BIT(30))
#define HZIP_SVA_PREFETCH_NUM GENMASK(18, 16)
#define HZIP_SVA_STALL_NUM GENMASK(15, 0)
#define HZIP_SHAPER_RATE_COMPRESS 750
#define HZIP_SHAPER_RATE_DECOMPRESS 140
#define HZIP_DELAY_1_US 1
#define HZIP_POLL_TIMEOUT_US 1000
#define HZIP_DELAY_1_US 1
#define HZIP_POLL_TIMEOUT_US 1000
#define HZIP_WAIT_SVA_READY 500000
#define HZIP_READ_SVA_STATUS_TIMES 3
#define HZIP_WAIT_US_MIN 10
#define HZIP_WAIT_US_MAX 20
/* clock gating */
#define HZIP_PEH_CFG_AUTO_GATE 0x3011A8
@@ -462,24 +468,31 @@ static void hisi_zip_set_high_perf(struct hisi_qm *qm)
writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET);
}
static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
static int hisi_zip_wait_sva_ready(struct hisi_qm *qm, __u32 offset, __u32 mask)
{
u32 val;
int ret;
u32 val, try_times = 0;
u8 count = 0;
if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
return;
/*
* 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 == HZIP_READ_SVA_STATUS_TIMES)
break;
/* Enable prefetch */
val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
val &= HZIP_PREFETCH_ENABLE;
writel(val, qm->io_base + HZIP_PREFETCH_CFG);
usleep_range(HZIP_WAIT_US_MIN, HZIP_WAIT_US_MAX);
} while (++try_times < HZIP_WAIT_SVA_READY);
ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_PREFETCH_CFG,
val, !(val & HZIP_SVA_PREFETCH_DISABLE),
HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);
if (ret)
pci_err(qm->pdev, "failed to open sva prefetch\n");
if (try_times == HZIP_WAIT_SVA_READY) {
pci_err(qm->pdev, "failed to wait sva prefetch ready\n");
return -ETIMEDOUT;
}
return 0;
}
static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)
@@ -499,6 +512,35 @@ static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)
HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);
if (ret)
pci_err(qm->pdev, "failed to close sva prefetch\n");
(void)hisi_zip_wait_sva_ready(qm, HZIP_SVA_TRANS, HZIP_SVA_STALL_NUM);
}
static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
{
u32 val;
int ret;
if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
return;
/* Enable prefetch */
val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
val &= HZIP_PREFETCH_ENABLE;
writel(val, qm->io_base + HZIP_PREFETCH_CFG);
ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_PREFETCH_CFG,
val, !(val & HZIP_SVA_PREFETCH_DISABLE),
HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);
if (ret) {
pci_err(qm->pdev, "failed to open sva prefetch\n");
hisi_zip_close_sva_prefetch(qm);
return;
}
ret = hisi_zip_wait_sva_ready(qm, HZIP_SVA_TRANS, HZIP_SVA_PREFETCH_NUM);
if (ret)
hisi_zip_close_sva_prefetch(qm);
}
static void hisi_zip_enable_clock_gate(struct hisi_qm *qm)
@@ -522,6 +564,7 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
void __iomem *base = qm->io_base;
u32 dcomp_bm, comp_bm;
u32 zip_core_en;
int ret;
/* qm user domain */
writel(AXUSER_BASE, base + QM_ARUSER_M_CFG_1);
@@ -576,7 +619,15 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
hisi_zip_set_high_perf(qm);
hisi_zip_enable_clock_gate(qm);
return hisi_dae_set_user_domain(qm);
ret = hisi_dae_set_user_domain(qm);
if (ret)
goto close_sva_prefetch;
return 0;
close_sva_prefetch:
hisi_zip_close_sva_prefetch(qm);
return ret;
}
static void hisi_zip_master_ooo_ctrl(struct hisi_qm *qm, bool enable)