summaryrefslogtreecommitdiff
path: root/drivers/crypto/hisilicon/zip/zip_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/crypto/hisilicon/zip/zip_main.c')
-rw-r--r--drivers/crypto/hisilicon/zip/zip_main.c229
1 files changed, 154 insertions, 75 deletions
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
index db4c964cd649..479ba8a1d6b5 100644
--- a/drivers/crypto/hisilicon/zip/zip_main.c
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -74,7 +74,6 @@
#define HZIP_AXI_SHUTDOWN_ENABLE BIT(14)
#define HZIP_WR_PORT BIT(11)
-#define HZIP_DEV_ALG_MAX_LEN 256
#define HZIP_ALG_ZLIB_BIT GENMASK(1, 0)
#define HZIP_ALG_GZIP_BIT GENMASK(3, 2)
#define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4)
@@ -107,6 +106,14 @@
#define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \
HZIP_CORE_GATED_OOO_EN)
+/* zip comp high performance */
+#define HZIP_HIGH_PERF_OFFSET 0x301208
+
+enum {
+ HZIP_HIGH_COMP_RATE,
+ HZIP_HIGH_COMP_PERF,
+};
+
static const char hisi_zip_name[] = "hisi_zip";
static struct dentry *hzip_debugfs_root;
@@ -120,23 +127,18 @@ struct zip_dfx_item {
u32 offset;
};
-struct zip_dev_alg {
- u32 alg_msk;
- const char *algs;
-};
-
-static const struct zip_dev_alg zip_dev_algs[] = { {
+static const struct qm_dev_alg zip_dev_algs[] = { {
.alg_msk = HZIP_ALG_ZLIB_BIT,
- .algs = "zlib\n",
+ .alg = "zlib\n",
}, {
.alg_msk = HZIP_ALG_GZIP_BIT,
- .algs = "gzip\n",
+ .alg = "gzip\n",
}, {
.alg_msk = HZIP_ALG_DEFLATE_BIT,
- .algs = "deflate\n",
+ .alg = "deflate\n",
}, {
.alg_msk = HZIP_ALG_LZ77_BIT,
- .algs = "lz77_zstd\n",
+ .alg = "lz77_zstd\n",
},
};
@@ -247,6 +249,26 @@ static struct hisi_qm_cap_info zip_basic_cap_info[] = {
{ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0}
};
+enum zip_pre_store_cap_idx {
+ ZIP_CORE_NUM_CAP_IDX = 0x0,
+ ZIP_CLUSTER_COMP_NUM_CAP_IDX,
+ ZIP_CLUSTER_DECOMP_NUM_CAP_IDX,
+ ZIP_DECOMP_ENABLE_BITMAP_IDX,
+ ZIP_COMP_ENABLE_BITMAP_IDX,
+ ZIP_DRV_ALG_BITMAP_IDX,
+ ZIP_DEV_ALG_BITMAP_IDX,
+};
+
+static const u32 zip_pre_store_caps[] = {
+ ZIP_CORE_NUM_CAP,
+ ZIP_CLUSTER_COMP_NUM_CAP,
+ ZIP_CLUSTER_DECOMP_NUM_CAP,
+ ZIP_DECOMP_ENABLE_BITMAP,
+ ZIP_COMP_ENABLE_BITMAP,
+ ZIP_DRV_ALG_BITMAP,
+ ZIP_DEV_ALG_BITMAP,
+};
+
enum {
HZIP_COMP_CORE0,
HZIP_COMP_CORE1,
@@ -270,28 +292,28 @@ static const u64 core_offsets[] = {
};
static const struct debugfs_reg32 hzip_dfx_regs[] = {
- {"HZIP_GET_BD_NUM ", 0x00ull},
- {"HZIP_GET_RIGHT_BD ", 0x04ull},
- {"HZIP_GET_ERROR_BD ", 0x08ull},
- {"HZIP_DONE_BD_NUM ", 0x0cull},
- {"HZIP_WORK_CYCLE ", 0x10ull},
- {"HZIP_IDLE_CYCLE ", 0x18ull},
- {"HZIP_MAX_DELAY ", 0x20ull},
- {"HZIP_MIN_DELAY ", 0x24ull},
- {"HZIP_AVG_DELAY ", 0x28ull},
- {"HZIP_MEM_VISIBLE_DATA ", 0x30ull},
- {"HZIP_MEM_VISIBLE_ADDR ", 0x34ull},
- {"HZIP_CONSUMED_BYTE ", 0x38ull},
- {"HZIP_PRODUCED_BYTE ", 0x40ull},
- {"HZIP_COMP_INF ", 0x70ull},
- {"HZIP_PRE_OUT ", 0x78ull},
- {"HZIP_BD_RD ", 0x7cull},
- {"HZIP_BD_WR ", 0x80ull},
- {"HZIP_GET_BD_AXI_ERR_NUM ", 0x84ull},
- {"HZIP_GET_BD_PARSE_ERR_NUM ", 0x88ull},
- {"HZIP_ADD_BD_AXI_ERR_NUM ", 0x8cull},
- {"HZIP_DECOMP_STF_RELOAD_CURR_ST ", 0x94ull},
- {"HZIP_DECOMP_LZ77_CURR_ST ", 0x9cull},
+ {"HZIP_GET_BD_NUM ", 0x00},
+ {"HZIP_GET_RIGHT_BD ", 0x04},
+ {"HZIP_GET_ERROR_BD ", 0x08},
+ {"HZIP_DONE_BD_NUM ", 0x0c},
+ {"HZIP_WORK_CYCLE ", 0x10},
+ {"HZIP_IDLE_CYCLE ", 0x18},
+ {"HZIP_MAX_DELAY ", 0x20},
+ {"HZIP_MIN_DELAY ", 0x24},
+ {"HZIP_AVG_DELAY ", 0x28},
+ {"HZIP_MEM_VISIBLE_DATA ", 0x30},
+ {"HZIP_MEM_VISIBLE_ADDR ", 0x34},
+ {"HZIP_CONSUMED_BYTE ", 0x38},
+ {"HZIP_PRODUCED_BYTE ", 0x40},
+ {"HZIP_COMP_INF ", 0x70},
+ {"HZIP_PRE_OUT ", 0x78},
+ {"HZIP_BD_RD ", 0x7c},
+ {"HZIP_BD_WR ", 0x80},
+ {"HZIP_GET_BD_AXI_ERR_NUM ", 0x84},
+ {"HZIP_GET_BD_PARSE_ERR_NUM ", 0x88},
+ {"HZIP_ADD_BD_AXI_ERR_NUM ", 0x8c},
+ {"HZIP_DECOMP_STF_RELOAD_CURR_ST ", 0x94},
+ {"HZIP_DECOMP_LZ77_CURR_ST ", 0x9c},
};
static const struct debugfs_reg32 hzip_com_dfx_regs[] = {
@@ -303,11 +325,11 @@ static const struct debugfs_reg32 hzip_com_dfx_regs[] = {
};
static const struct debugfs_reg32 hzip_dump_dfx_regs[] = {
- {"HZIP_GET_BD_NUM ", 0x00ull},
- {"HZIP_GET_RIGHT_BD ", 0x04ull},
- {"HZIP_GET_ERROR_BD ", 0x08ull},
- {"HZIP_DONE_BD_NUM ", 0x0cull},
- {"HZIP_MAX_DELAY ", 0x20ull},
+ {"HZIP_GET_BD_NUM ", 0x00},
+ {"HZIP_GET_RIGHT_BD ", 0x04},
+ {"HZIP_GET_ERROR_BD ", 0x08},
+ {"HZIP_DONE_BD_NUM ", 0x0c},
+ {"HZIP_MAX_DELAY ", 0x20},
};
/* define the ZIP's dfx regs region and region length */
@@ -352,6 +374,37 @@ static int hzip_diff_regs_show(struct seq_file *s, void *unused)
return 0;
}
DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs);
+
+static int perf_mode_set(const char *val, const struct kernel_param *kp)
+{
+ int ret;
+ u32 n;
+
+ if (!val)
+ return -EINVAL;
+
+ ret = kstrtou32(val, 10, &n);
+ if (ret != 0 || (n != HZIP_HIGH_COMP_PERF &&
+ n != HZIP_HIGH_COMP_RATE))
+ return -EINVAL;
+
+ return param_set_int(val, kp);
+}
+
+static const struct kernel_param_ops zip_com_perf_ops = {
+ .set = perf_mode_set,
+ .get = param_get_int,
+};
+
+/*
+ * perf_mode = 0 means enable high compression rate mode,
+ * perf_mode = 1 means enable high compression performance mode.
+ * These two modes only apply to the compression direction.
+ */
+static u32 perf_mode = HZIP_HIGH_COMP_RATE;
+module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444);
+MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)");
+
static const struct kernel_param_ops zip_uacce_mode_ops = {
.set = uacce_mode_set,
.get = param_get_int,
@@ -410,40 +463,33 @@ bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg)
{
u32 cap_val;
- cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver);
+ cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val;
if ((alg & cap_val) == alg)
return true;
return false;
}
-static int hisi_zip_set_qm_algs(struct hisi_qm *qm)
+static int hisi_zip_set_high_perf(struct hisi_qm *qm)
{
- struct device *dev = &qm->pdev->dev;
- char *algs, *ptr;
- u32 alg_mask;
- int i;
-
- if (!qm->use_sva)
- return 0;
-
- algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL);
- if (!algs)
- return -ENOMEM;
-
- alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver);
-
- for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++)
- if (alg_mask & zip_dev_algs[i].alg_msk)
- strcat(algs, zip_dev_algs[i].algs);
-
- ptr = strrchr(algs, '\n');
- if (ptr)
- *ptr = '\0';
+ u32 val;
+ int ret;
- qm->uacce->algs = algs;
+ val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET);
+ if (perf_mode == HZIP_HIGH_COMP_PERF)
+ val |= HZIP_HIGH_COMP_PERF;
+ else
+ val &= ~HZIP_HIGH_COMP_PERF;
+
+ /* Set perf mode */
+ writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET);
+ ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET,
+ val, val == perf_mode, HZIP_DELAY_1_US,
+ HZIP_POLL_TIMEOUT_US);
+ if (ret)
+ pci_err(qm->pdev, "failed to set perf mode\n");
- return 0;
+ return ret;
}
static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
@@ -542,10 +588,8 @@ static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
}
/* let's open all compression/decompression cores */
- dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
- ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver);
- comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
- ZIP_COMP_ENABLE_BITMAP, qm->cap_ver);
+ dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val;
+ comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val;
writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL);
/* enable sqc,cqc writeback */
@@ -772,9 +816,8 @@ static int hisi_zip_core_debug_init(struct hisi_qm *qm)
char buf[HZIP_BUF_SIZE];
int i;
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP,
- qm->cap_ver);
+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
+ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
for (i = 0; i < zip_core_num; i++) {
if (i < zip_comp_core_num)
@@ -916,7 +959,7 @@ static int hisi_zip_show_last_regs_init(struct hisi_qm *qm)
u32 zip_core_num;
int i, j, idx;
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num,
sizeof(unsigned int), GFP_KERNEL);
@@ -972,9 +1015,9 @@ static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm)
hzip_com_dfx_regs[i].name, debug->last_words[i], val);
}
- zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver);
- zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP,
- qm->cap_ver);
+ zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
+ zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
+
for (i = 0; i < zip_core_num; i++) {
if (i < zip_comp_core_num)
scnprintf(buf, sizeof(buf), "Comp_core-%d", i);
@@ -1115,6 +1158,10 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
if (ret)
return ret;
+ ret = hisi_zip_set_high_perf(qm);
+ if (ret)
+ return ret;
+
hisi_zip_open_sva_prefetch(qm);
hisi_qm_dev_err_init(qm);
hisi_zip_debug_regs_clear(qm);
@@ -1126,8 +1173,31 @@ static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
return ret;
}
+static int zip_pre_store_cap_reg(struct hisi_qm *qm)
+{
+ struct hisi_qm_cap_record *zip_cap;
+ struct pci_dev *pdev = qm->pdev;
+ size_t i, size;
+
+ size = ARRAY_SIZE(zip_pre_store_caps);
+ zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL);
+ if (!zip_cap)
+ return -ENOMEM;
+
+ for (i = 0; i < size; i++) {
+ zip_cap[i].type = zip_pre_store_caps[i];
+ zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
+ zip_pre_store_caps[i], qm->cap_ver);
+ }
+
+ qm->cap_tables.dev_cap_table = zip_cap;
+
+ return 0;
+}
+
static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
{
+ u64 alg_msk;
int ret;
qm->pdev = pdev;
@@ -1163,7 +1233,16 @@ static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
return ret;
}
- ret = hisi_zip_set_qm_algs(qm);
+ /* Fetch and save the value of capability registers */
+ ret = zip_pre_store_cap_reg(qm);
+ if (ret) {
+ pci_err(qm->pdev, "Failed to pre-store capability registers!\n");
+ hisi_qm_uninit(qm);
+ return ret;
+ }
+
+ alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val;
+ ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs));
if (ret) {
pci_err(qm->pdev, "Failed to set zip algs!\n");
hisi_qm_uninit(qm);