162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright (c) 2019 HiSilicon Limited. */
362306a36Sopenharmony_ci#include <linux/acpi.h>
462306a36Sopenharmony_ci#include <linux/bitops.h>
562306a36Sopenharmony_ci#include <linux/debugfs.h>
662306a36Sopenharmony_ci#include <linux/init.h>
762306a36Sopenharmony_ci#include <linux/io.h>
862306a36Sopenharmony_ci#include <linux/kernel.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/pci.h>
1162306a36Sopenharmony_ci#include <linux/pm_runtime.h>
1262306a36Sopenharmony_ci#include <linux/seq_file.h>
1362306a36Sopenharmony_ci#include <linux/topology.h>
1462306a36Sopenharmony_ci#include <linux/uacce.h>
1562306a36Sopenharmony_ci#include "zip.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define PCI_DEVICE_ID_HUAWEI_ZIP_PF	0xa250
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define HZIP_QUEUE_NUM_V1		4096
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define HZIP_CLOCK_GATE_CTRL		0x301004
2262306a36Sopenharmony_ci#define HZIP_DECOMP_CHECK_ENABLE	BIT(16)
2362306a36Sopenharmony_ci#define HZIP_FSM_MAX_CNT		0x301008
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define HZIP_PORT_ARCA_CHE_0		0x301040
2662306a36Sopenharmony_ci#define HZIP_PORT_ARCA_CHE_1		0x301044
2762306a36Sopenharmony_ci#define HZIP_PORT_AWCA_CHE_0		0x301060
2862306a36Sopenharmony_ci#define HZIP_PORT_AWCA_CHE_1		0x301064
2962306a36Sopenharmony_ci#define HZIP_CACHE_ALL_EN		0xffffffff
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define HZIP_BD_RUSER_32_63		0x301110
3262306a36Sopenharmony_ci#define HZIP_SGL_RUSER_32_63		0x30111c
3362306a36Sopenharmony_ci#define HZIP_DATA_RUSER_32_63		0x301128
3462306a36Sopenharmony_ci#define HZIP_DATA_WUSER_32_63		0x301134
3562306a36Sopenharmony_ci#define HZIP_BD_WUSER_32_63		0x301140
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define HZIP_QM_IDEL_STATUS		0x3040e4
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define HZIP_CORE_DFX_BASE		0x301000
4062306a36Sopenharmony_ci#define HZIP_CLOCK_GATED_CONTL		0X301004
4162306a36Sopenharmony_ci#define HZIP_CORE_DFX_COMP_0		0x302000
4262306a36Sopenharmony_ci#define HZIP_CORE_DFX_COMP_1		0x303000
4362306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_0		0x304000
4462306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_1		0x305000
4562306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_2		0x306000
4662306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_3		0x307000
4762306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_4		0x308000
4862306a36Sopenharmony_ci#define HZIP_CORE_DFX_DECOMP_5		0x309000
4962306a36Sopenharmony_ci#define HZIP_CORE_REGS_BASE_LEN		0xB0
5062306a36Sopenharmony_ci#define HZIP_CORE_REGS_DFX_LEN		0x28
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#define HZIP_CORE_INT_SOURCE		0x3010A0
5362306a36Sopenharmony_ci#define HZIP_CORE_INT_MASK_REG		0x3010A4
5462306a36Sopenharmony_ci#define HZIP_CORE_INT_SET		0x3010A8
5562306a36Sopenharmony_ci#define HZIP_CORE_INT_STATUS		0x3010AC
5662306a36Sopenharmony_ci#define HZIP_CORE_INT_STATUS_M_ECC	BIT(1)
5762306a36Sopenharmony_ci#define HZIP_CORE_SRAM_ECC_ERR_INFO	0x301148
5862306a36Sopenharmony_ci#define HZIP_CORE_INT_RAS_CE_ENB	0x301160
5962306a36Sopenharmony_ci#define HZIP_CORE_INT_RAS_NFE_ENB	0x301164
6062306a36Sopenharmony_ci#define HZIP_CORE_INT_RAS_FE_ENB        0x301168
6162306a36Sopenharmony_ci#define HZIP_CORE_INT_RAS_FE_ENB_MASK	0x0
6262306a36Sopenharmony_ci#define HZIP_OOO_SHUTDOWN_SEL		0x30120C
6362306a36Sopenharmony_ci#define HZIP_SRAM_ECC_ERR_NUM_SHIFT	16
6462306a36Sopenharmony_ci#define HZIP_SRAM_ECC_ERR_ADDR_SHIFT	24
6562306a36Sopenharmony_ci#define HZIP_CORE_INT_MASK_ALL		GENMASK(12, 0)
6662306a36Sopenharmony_ci#define HZIP_SQE_SIZE			128
6762306a36Sopenharmony_ci#define HZIP_PF_DEF_Q_NUM		64
6862306a36Sopenharmony_ci#define HZIP_PF_DEF_Q_BASE		0
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#define HZIP_SOFT_CTRL_CNT_CLR_CE	0x301000
7162306a36Sopenharmony_ci#define HZIP_SOFT_CTRL_CNT_CLR_CE_BIT	BIT(0)
7262306a36Sopenharmony_ci#define HZIP_SOFT_CTRL_ZIP_CONTROL	0x30100C
7362306a36Sopenharmony_ci#define HZIP_AXI_SHUTDOWN_ENABLE	BIT(14)
7462306a36Sopenharmony_ci#define HZIP_WR_PORT			BIT(11)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define HZIP_ALG_ZLIB_BIT		GENMASK(1, 0)
7762306a36Sopenharmony_ci#define HZIP_ALG_GZIP_BIT		GENMASK(3, 2)
7862306a36Sopenharmony_ci#define HZIP_ALG_DEFLATE_BIT		GENMASK(5, 4)
7962306a36Sopenharmony_ci#define HZIP_ALG_LZ77_BIT		GENMASK(7, 6)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#define HZIP_BUF_SIZE			22
8262306a36Sopenharmony_ci#define HZIP_SQE_MASK_OFFSET		64
8362306a36Sopenharmony_ci#define HZIP_SQE_MASK_LEN		48
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define HZIP_CNT_CLR_CE_EN		BIT(0)
8662306a36Sopenharmony_ci#define HZIP_RO_CNT_CLR_CE_EN		BIT(2)
8762306a36Sopenharmony_ci#define HZIP_RD_CNT_CLR_CE_EN		(HZIP_CNT_CLR_CE_EN | \
8862306a36Sopenharmony_ci					 HZIP_RO_CNT_CLR_CE_EN)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#define HZIP_PREFETCH_CFG		0x3011B0
9162306a36Sopenharmony_ci#define HZIP_SVA_TRANS			0x3011C4
9262306a36Sopenharmony_ci#define HZIP_PREFETCH_ENABLE		(~(BIT(26) | BIT(17) | BIT(0)))
9362306a36Sopenharmony_ci#define HZIP_SVA_PREFETCH_DISABLE	BIT(26)
9462306a36Sopenharmony_ci#define HZIP_SVA_DISABLE_READY		(BIT(26) | BIT(30))
9562306a36Sopenharmony_ci#define HZIP_SHAPER_RATE_COMPRESS	750
9662306a36Sopenharmony_ci#define HZIP_SHAPER_RATE_DECOMPRESS	140
9762306a36Sopenharmony_ci#define HZIP_DELAY_1_US		1
9862306a36Sopenharmony_ci#define HZIP_POLL_TIMEOUT_US	1000
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* clock gating */
10162306a36Sopenharmony_ci#define HZIP_PEH_CFG_AUTO_GATE		0x3011A8
10262306a36Sopenharmony_ci#define HZIP_PEH_CFG_AUTO_GATE_EN	BIT(0)
10362306a36Sopenharmony_ci#define HZIP_CORE_GATED_EN		GENMASK(15, 8)
10462306a36Sopenharmony_ci#define HZIP_CORE_GATED_OOO_EN		BIT(29)
10562306a36Sopenharmony_ci#define HZIP_CLOCK_GATED_EN		(HZIP_CORE_GATED_EN | \
10662306a36Sopenharmony_ci					 HZIP_CORE_GATED_OOO_EN)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* zip comp high performance */
10962306a36Sopenharmony_ci#define HZIP_HIGH_PERF_OFFSET		0x301208
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cienum {
11262306a36Sopenharmony_ci	HZIP_HIGH_COMP_RATE,
11362306a36Sopenharmony_ci	HZIP_HIGH_COMP_PERF,
11462306a36Sopenharmony_ci};
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic const char hisi_zip_name[] = "hisi_zip";
11762306a36Sopenharmony_cistatic struct dentry *hzip_debugfs_root;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_cistruct hisi_zip_hw_error {
12062306a36Sopenharmony_ci	u32 int_msk;
12162306a36Sopenharmony_ci	const char *msg;
12262306a36Sopenharmony_ci};
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistruct zip_dfx_item {
12562306a36Sopenharmony_ci	const char *name;
12662306a36Sopenharmony_ci	u32 offset;
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistatic const struct qm_dev_alg zip_dev_algs[] = { {
13062306a36Sopenharmony_ci		.alg_msk = HZIP_ALG_ZLIB_BIT,
13162306a36Sopenharmony_ci		.alg = "zlib\n",
13262306a36Sopenharmony_ci	}, {
13362306a36Sopenharmony_ci		.alg_msk = HZIP_ALG_GZIP_BIT,
13462306a36Sopenharmony_ci		.alg = "gzip\n",
13562306a36Sopenharmony_ci	}, {
13662306a36Sopenharmony_ci		.alg_msk = HZIP_ALG_DEFLATE_BIT,
13762306a36Sopenharmony_ci		.alg = "deflate\n",
13862306a36Sopenharmony_ci	}, {
13962306a36Sopenharmony_ci		.alg_msk = HZIP_ALG_LZ77_BIT,
14062306a36Sopenharmony_ci		.alg = "lz77_zstd\n",
14162306a36Sopenharmony_ci	},
14262306a36Sopenharmony_ci};
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic struct hisi_qm_list zip_devices = {
14562306a36Sopenharmony_ci	.register_to_crypto	= hisi_zip_register_to_crypto,
14662306a36Sopenharmony_ci	.unregister_from_crypto	= hisi_zip_unregister_from_crypto,
14762306a36Sopenharmony_ci};
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic struct zip_dfx_item zip_dfx_files[] = {
15062306a36Sopenharmony_ci	{"send_cnt", offsetof(struct hisi_zip_dfx, send_cnt)},
15162306a36Sopenharmony_ci	{"recv_cnt", offsetof(struct hisi_zip_dfx, recv_cnt)},
15262306a36Sopenharmony_ci	{"send_busy_cnt", offsetof(struct hisi_zip_dfx, send_busy_cnt)},
15362306a36Sopenharmony_ci	{"err_bd_cnt", offsetof(struct hisi_zip_dfx, err_bd_cnt)},
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistatic const struct hisi_zip_hw_error zip_hw_error[] = {
15762306a36Sopenharmony_ci	{ .int_msk = BIT(0), .msg = "zip_ecc_1bitt_err" },
15862306a36Sopenharmony_ci	{ .int_msk = BIT(1), .msg = "zip_ecc_2bit_err" },
15962306a36Sopenharmony_ci	{ .int_msk = BIT(2), .msg = "zip_axi_rresp_err" },
16062306a36Sopenharmony_ci	{ .int_msk = BIT(3), .msg = "zip_axi_bresp_err" },
16162306a36Sopenharmony_ci	{ .int_msk = BIT(4), .msg = "zip_src_addr_parse_err" },
16262306a36Sopenharmony_ci	{ .int_msk = BIT(5), .msg = "zip_dst_addr_parse_err" },
16362306a36Sopenharmony_ci	{ .int_msk = BIT(6), .msg = "zip_pre_in_addr_err" },
16462306a36Sopenharmony_ci	{ .int_msk = BIT(7), .msg = "zip_pre_in_data_err" },
16562306a36Sopenharmony_ci	{ .int_msk = BIT(8), .msg = "zip_com_inf_err" },
16662306a36Sopenharmony_ci	{ .int_msk = BIT(9), .msg = "zip_enc_inf_err" },
16762306a36Sopenharmony_ci	{ .int_msk = BIT(10), .msg = "zip_pre_out_err" },
16862306a36Sopenharmony_ci	{ .int_msk = BIT(11), .msg = "zip_axi_poison_err" },
16962306a36Sopenharmony_ci	{ .int_msk = BIT(12), .msg = "zip_sva_err" },
17062306a36Sopenharmony_ci	{ /* sentinel */ }
17162306a36Sopenharmony_ci};
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cienum ctrl_debug_file_index {
17462306a36Sopenharmony_ci	HZIP_CLEAR_ENABLE,
17562306a36Sopenharmony_ci	HZIP_DEBUG_FILE_NUM,
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic const char * const ctrl_debug_file_name[] = {
17962306a36Sopenharmony_ci	[HZIP_CLEAR_ENABLE] = "clear_enable",
18062306a36Sopenharmony_ci};
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_cistruct ctrl_debug_file {
18362306a36Sopenharmony_ci	enum ctrl_debug_file_index index;
18462306a36Sopenharmony_ci	spinlock_t lock;
18562306a36Sopenharmony_ci	struct hisi_zip_ctrl *ctrl;
18662306a36Sopenharmony_ci};
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci/*
18962306a36Sopenharmony_ci * One ZIP controller has one PF and multiple VFs, some global configurations
19062306a36Sopenharmony_ci * which PF has need this structure.
19162306a36Sopenharmony_ci *
19262306a36Sopenharmony_ci * Just relevant for PF.
19362306a36Sopenharmony_ci */
19462306a36Sopenharmony_cistruct hisi_zip_ctrl {
19562306a36Sopenharmony_ci	struct hisi_zip *hisi_zip;
19662306a36Sopenharmony_ci	struct ctrl_debug_file files[HZIP_DEBUG_FILE_NUM];
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cienum zip_cap_type {
20062306a36Sopenharmony_ci	ZIP_QM_NFE_MASK_CAP = 0x0,
20162306a36Sopenharmony_ci	ZIP_QM_RESET_MASK_CAP,
20262306a36Sopenharmony_ci	ZIP_QM_OOO_SHUTDOWN_MASK_CAP,
20362306a36Sopenharmony_ci	ZIP_QM_CE_MASK_CAP,
20462306a36Sopenharmony_ci	ZIP_NFE_MASK_CAP,
20562306a36Sopenharmony_ci	ZIP_RESET_MASK_CAP,
20662306a36Sopenharmony_ci	ZIP_OOO_SHUTDOWN_MASK_CAP,
20762306a36Sopenharmony_ci	ZIP_CE_MASK_CAP,
20862306a36Sopenharmony_ci	ZIP_CLUSTER_NUM_CAP,
20962306a36Sopenharmony_ci	ZIP_CORE_TYPE_NUM_CAP,
21062306a36Sopenharmony_ci	ZIP_CORE_NUM_CAP,
21162306a36Sopenharmony_ci	ZIP_CLUSTER_COMP_NUM_CAP,
21262306a36Sopenharmony_ci	ZIP_CLUSTER_DECOMP_NUM_CAP,
21362306a36Sopenharmony_ci	ZIP_DECOMP_ENABLE_BITMAP,
21462306a36Sopenharmony_ci	ZIP_COMP_ENABLE_BITMAP,
21562306a36Sopenharmony_ci	ZIP_DRV_ALG_BITMAP,
21662306a36Sopenharmony_ci	ZIP_DEV_ALG_BITMAP,
21762306a36Sopenharmony_ci	ZIP_CORE1_ALG_BITMAP,
21862306a36Sopenharmony_ci	ZIP_CORE2_ALG_BITMAP,
21962306a36Sopenharmony_ci	ZIP_CORE3_ALG_BITMAP,
22062306a36Sopenharmony_ci	ZIP_CORE4_ALG_BITMAP,
22162306a36Sopenharmony_ci	ZIP_CORE5_ALG_BITMAP,
22262306a36Sopenharmony_ci	ZIP_CAP_MAX
22362306a36Sopenharmony_ci};
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_cistatic struct hisi_qm_cap_info zip_basic_cap_info[] = {
22662306a36Sopenharmony_ci	{ZIP_QM_NFE_MASK_CAP, 0x3124, 0, GENMASK(31, 0), 0x0, 0x1C57, 0x7C77},
22762306a36Sopenharmony_ci	{ZIP_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC57, 0x6C77},
22862306a36Sopenharmony_ci	{ZIP_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C77},
22962306a36Sopenharmony_ci	{ZIP_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8},
23062306a36Sopenharmony_ci	{ZIP_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x7FE, 0x1FFE},
23162306a36Sopenharmony_ci	{ZIP_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x7FE, 0x7FE},
23262306a36Sopenharmony_ci	{ZIP_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x2, 0x7FE},
23362306a36Sopenharmony_ci	{ZIP_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x1, 0x1},
23462306a36Sopenharmony_ci	{ZIP_CLUSTER_NUM_CAP, 0x313C, 28, GENMASK(3, 0), 0x1, 0x1, 0x1},
23562306a36Sopenharmony_ci	{ZIP_CORE_TYPE_NUM_CAP, 0x313C, 24, GENMASK(3, 0), 0x2, 0x2, 0x2},
23662306a36Sopenharmony_ci	{ZIP_CORE_NUM_CAP, 0x313C, 16, GENMASK(7, 0), 0x8, 0x8, 0x5},
23762306a36Sopenharmony_ci	{ZIP_CLUSTER_COMP_NUM_CAP, 0x313C, 8, GENMASK(7, 0), 0x2, 0x2, 0x2},
23862306a36Sopenharmony_ci	{ZIP_CLUSTER_DECOMP_NUM_CAP, 0x313C, 0, GENMASK(7, 0), 0x6, 0x6, 0x3},
23962306a36Sopenharmony_ci	{ZIP_DECOMP_ENABLE_BITMAP, 0x3140, 16, GENMASK(15, 0), 0xFC, 0xFC, 0x1C},
24062306a36Sopenharmony_ci	{ZIP_COMP_ENABLE_BITMAP, 0x3140, 0, GENMASK(15, 0), 0x3, 0x3, 0x3},
24162306a36Sopenharmony_ci	{ZIP_DRV_ALG_BITMAP, 0x3144, 0, GENMASK(31, 0), 0xF, 0xF, 0xF},
24262306a36Sopenharmony_ci	{ZIP_DEV_ALG_BITMAP, 0x3148, 0, GENMASK(31, 0), 0xF, 0xF, 0xFF},
24362306a36Sopenharmony_ci	{ZIP_CORE1_ALG_BITMAP, 0x314C, 0, GENMASK(31, 0), 0x5, 0x5, 0xD5},
24462306a36Sopenharmony_ci	{ZIP_CORE2_ALG_BITMAP, 0x3150, 0, GENMASK(31, 0), 0x5, 0x5, 0xD5},
24562306a36Sopenharmony_ci	{ZIP_CORE3_ALG_BITMAP, 0x3154, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},
24662306a36Sopenharmony_ci	{ZIP_CORE4_ALG_BITMAP, 0x3158, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},
24762306a36Sopenharmony_ci	{ZIP_CORE5_ALG_BITMAP, 0x315C, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},
24862306a36Sopenharmony_ci	{ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0}
24962306a36Sopenharmony_ci};
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cienum zip_pre_store_cap_idx {
25262306a36Sopenharmony_ci	ZIP_CORE_NUM_CAP_IDX = 0x0,
25362306a36Sopenharmony_ci	ZIP_CLUSTER_COMP_NUM_CAP_IDX,
25462306a36Sopenharmony_ci	ZIP_CLUSTER_DECOMP_NUM_CAP_IDX,
25562306a36Sopenharmony_ci	ZIP_DECOMP_ENABLE_BITMAP_IDX,
25662306a36Sopenharmony_ci	ZIP_COMP_ENABLE_BITMAP_IDX,
25762306a36Sopenharmony_ci	ZIP_DRV_ALG_BITMAP_IDX,
25862306a36Sopenharmony_ci	ZIP_DEV_ALG_BITMAP_IDX,
25962306a36Sopenharmony_ci};
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic const u32 zip_pre_store_caps[] = {
26262306a36Sopenharmony_ci	ZIP_CORE_NUM_CAP,
26362306a36Sopenharmony_ci	ZIP_CLUSTER_COMP_NUM_CAP,
26462306a36Sopenharmony_ci	ZIP_CLUSTER_DECOMP_NUM_CAP,
26562306a36Sopenharmony_ci	ZIP_DECOMP_ENABLE_BITMAP,
26662306a36Sopenharmony_ci	ZIP_COMP_ENABLE_BITMAP,
26762306a36Sopenharmony_ci	ZIP_DRV_ALG_BITMAP,
26862306a36Sopenharmony_ci	ZIP_DEV_ALG_BITMAP,
26962306a36Sopenharmony_ci};
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_cienum {
27262306a36Sopenharmony_ci	HZIP_COMP_CORE0,
27362306a36Sopenharmony_ci	HZIP_COMP_CORE1,
27462306a36Sopenharmony_ci	HZIP_DECOMP_CORE0,
27562306a36Sopenharmony_ci	HZIP_DECOMP_CORE1,
27662306a36Sopenharmony_ci	HZIP_DECOMP_CORE2,
27762306a36Sopenharmony_ci	HZIP_DECOMP_CORE3,
27862306a36Sopenharmony_ci	HZIP_DECOMP_CORE4,
27962306a36Sopenharmony_ci	HZIP_DECOMP_CORE5,
28062306a36Sopenharmony_ci};
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_cistatic const u64 core_offsets[] = {
28362306a36Sopenharmony_ci	[HZIP_COMP_CORE0]   = 0x302000,
28462306a36Sopenharmony_ci	[HZIP_COMP_CORE1]   = 0x303000,
28562306a36Sopenharmony_ci	[HZIP_DECOMP_CORE0] = 0x304000,
28662306a36Sopenharmony_ci	[HZIP_DECOMP_CORE1] = 0x305000,
28762306a36Sopenharmony_ci	[HZIP_DECOMP_CORE2] = 0x306000,
28862306a36Sopenharmony_ci	[HZIP_DECOMP_CORE3] = 0x307000,
28962306a36Sopenharmony_ci	[HZIP_DECOMP_CORE4] = 0x308000,
29062306a36Sopenharmony_ci	[HZIP_DECOMP_CORE5] = 0x309000,
29162306a36Sopenharmony_ci};
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_cistatic const struct debugfs_reg32 hzip_dfx_regs[] = {
29462306a36Sopenharmony_ci	{"HZIP_GET_BD_NUM                ",  0x00ull},
29562306a36Sopenharmony_ci	{"HZIP_GET_RIGHT_BD              ",  0x04ull},
29662306a36Sopenharmony_ci	{"HZIP_GET_ERROR_BD              ",  0x08ull},
29762306a36Sopenharmony_ci	{"HZIP_DONE_BD_NUM               ",  0x0cull},
29862306a36Sopenharmony_ci	{"HZIP_WORK_CYCLE                ",  0x10ull},
29962306a36Sopenharmony_ci	{"HZIP_IDLE_CYCLE                ",  0x18ull},
30062306a36Sopenharmony_ci	{"HZIP_MAX_DELAY                 ",  0x20ull},
30162306a36Sopenharmony_ci	{"HZIP_MIN_DELAY                 ",  0x24ull},
30262306a36Sopenharmony_ci	{"HZIP_AVG_DELAY                 ",  0x28ull},
30362306a36Sopenharmony_ci	{"HZIP_MEM_VISIBLE_DATA          ",  0x30ull},
30462306a36Sopenharmony_ci	{"HZIP_MEM_VISIBLE_ADDR          ",  0x34ull},
30562306a36Sopenharmony_ci	{"HZIP_CONSUMED_BYTE             ",  0x38ull},
30662306a36Sopenharmony_ci	{"HZIP_PRODUCED_BYTE             ",  0x40ull},
30762306a36Sopenharmony_ci	{"HZIP_COMP_INF                  ",  0x70ull},
30862306a36Sopenharmony_ci	{"HZIP_PRE_OUT                   ",  0x78ull},
30962306a36Sopenharmony_ci	{"HZIP_BD_RD                     ",  0x7cull},
31062306a36Sopenharmony_ci	{"HZIP_BD_WR                     ",  0x80ull},
31162306a36Sopenharmony_ci	{"HZIP_GET_BD_AXI_ERR_NUM        ",  0x84ull},
31262306a36Sopenharmony_ci	{"HZIP_GET_BD_PARSE_ERR_NUM      ",  0x88ull},
31362306a36Sopenharmony_ci	{"HZIP_ADD_BD_AXI_ERR_NUM        ",  0x8cull},
31462306a36Sopenharmony_ci	{"HZIP_DECOMP_STF_RELOAD_CURR_ST ",  0x94ull},
31562306a36Sopenharmony_ci	{"HZIP_DECOMP_LZ77_CURR_ST       ",  0x9cull},
31662306a36Sopenharmony_ci};
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic const struct debugfs_reg32 hzip_com_dfx_regs[] = {
31962306a36Sopenharmony_ci	{"HZIP_CLOCK_GATE_CTRL           ",  0x301004},
32062306a36Sopenharmony_ci	{"HZIP_CORE_INT_RAS_CE_ENB       ",  0x301160},
32162306a36Sopenharmony_ci	{"HZIP_CORE_INT_RAS_NFE_ENB      ",  0x301164},
32262306a36Sopenharmony_ci	{"HZIP_CORE_INT_RAS_FE_ENB       ",  0x301168},
32362306a36Sopenharmony_ci	{"HZIP_UNCOM_ERR_RAS_CTRL        ",  0x30116C},
32462306a36Sopenharmony_ci};
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistatic const struct debugfs_reg32 hzip_dump_dfx_regs[] = {
32762306a36Sopenharmony_ci	{"HZIP_GET_BD_NUM                ",  0x00ull},
32862306a36Sopenharmony_ci	{"HZIP_GET_RIGHT_BD              ",  0x04ull},
32962306a36Sopenharmony_ci	{"HZIP_GET_ERROR_BD              ",  0x08ull},
33062306a36Sopenharmony_ci	{"HZIP_DONE_BD_NUM               ",  0x0cull},
33162306a36Sopenharmony_ci	{"HZIP_MAX_DELAY                 ",  0x20ull},
33262306a36Sopenharmony_ci};
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci/* define the ZIP's dfx regs region and region length */
33562306a36Sopenharmony_cistatic struct dfx_diff_registers hzip_diff_regs[] = {
33662306a36Sopenharmony_ci	{
33762306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_BASE,
33862306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_BASE_LEN,
33962306a36Sopenharmony_ci	}, {
34062306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_COMP_0,
34162306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
34262306a36Sopenharmony_ci	}, {
34362306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_COMP_1,
34462306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
34562306a36Sopenharmony_ci	}, {
34662306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_0,
34762306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
34862306a36Sopenharmony_ci	}, {
34962306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_1,
35062306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
35162306a36Sopenharmony_ci	}, {
35262306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_2,
35362306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
35462306a36Sopenharmony_ci	}, {
35562306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_3,
35662306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
35762306a36Sopenharmony_ci	}, {
35862306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_4,
35962306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
36062306a36Sopenharmony_ci	}, {
36162306a36Sopenharmony_ci		.reg_offset = HZIP_CORE_DFX_DECOMP_5,
36262306a36Sopenharmony_ci		.reg_len = HZIP_CORE_REGS_DFX_LEN,
36362306a36Sopenharmony_ci	},
36462306a36Sopenharmony_ci};
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_cistatic int hzip_diff_regs_show(struct seq_file *s, void *unused)
36762306a36Sopenharmony_ci{
36862306a36Sopenharmony_ci	struct hisi_qm *qm = s->private;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	hisi_qm_acc_diff_regs_dump(qm, s, qm->debug.acc_diff_regs,
37162306a36Sopenharmony_ci					ARRAY_SIZE(hzip_diff_regs));
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	return 0;
37462306a36Sopenharmony_ci}
37562306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(hzip_diff_regs);
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_cistatic int perf_mode_set(const char *val, const struct kernel_param *kp)
37862306a36Sopenharmony_ci{
37962306a36Sopenharmony_ci	int ret;
38062306a36Sopenharmony_ci	u32 n;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	if (!val)
38362306a36Sopenharmony_ci		return -EINVAL;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	ret = kstrtou32(val, 10, &n);
38662306a36Sopenharmony_ci	if (ret != 0 || (n != HZIP_HIGH_COMP_PERF &&
38762306a36Sopenharmony_ci			 n != HZIP_HIGH_COMP_RATE))
38862306a36Sopenharmony_ci		return -EINVAL;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	return param_set_int(val, kp);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic const struct kernel_param_ops zip_com_perf_ops = {
39462306a36Sopenharmony_ci	.set = perf_mode_set,
39562306a36Sopenharmony_ci	.get = param_get_int,
39662306a36Sopenharmony_ci};
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci/*
39962306a36Sopenharmony_ci * perf_mode = 0 means enable high compression rate mode,
40062306a36Sopenharmony_ci * perf_mode = 1 means enable high compression performance mode.
40162306a36Sopenharmony_ci * These two modes only apply to the compression direction.
40262306a36Sopenharmony_ci */
40362306a36Sopenharmony_cistatic u32 perf_mode = HZIP_HIGH_COMP_RATE;
40462306a36Sopenharmony_cimodule_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444);
40562306a36Sopenharmony_ciMODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)");
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_cistatic const struct kernel_param_ops zip_uacce_mode_ops = {
40862306a36Sopenharmony_ci	.set = uacce_mode_set,
40962306a36Sopenharmony_ci	.get = param_get_int,
41062306a36Sopenharmony_ci};
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci/*
41362306a36Sopenharmony_ci * uacce_mode = 0 means zip only register to crypto,
41462306a36Sopenharmony_ci * uacce_mode = 1 means zip both register to crypto and uacce.
41562306a36Sopenharmony_ci */
41662306a36Sopenharmony_cistatic u32 uacce_mode = UACCE_MODE_NOUACCE;
41762306a36Sopenharmony_cimodule_param_cb(uacce_mode, &zip_uacce_mode_ops, &uacce_mode, 0444);
41862306a36Sopenharmony_ciMODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_cistatic bool pf_q_num_flag;
42162306a36Sopenharmony_cistatic int pf_q_num_set(const char *val, const struct kernel_param *kp)
42262306a36Sopenharmony_ci{
42362306a36Sopenharmony_ci	pf_q_num_flag = true;
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci	return q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF);
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic const struct kernel_param_ops pf_q_num_ops = {
42962306a36Sopenharmony_ci	.set = pf_q_num_set,
43062306a36Sopenharmony_ci	.get = param_get_int,
43162306a36Sopenharmony_ci};
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_cistatic u32 pf_q_num = HZIP_PF_DEF_Q_NUM;
43462306a36Sopenharmony_cimodule_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444);
43562306a36Sopenharmony_ciMODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 2-4096, v2 2-1024)");
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_cistatic const struct kernel_param_ops vfs_num_ops = {
43862306a36Sopenharmony_ci	.set = vfs_num_set,
43962306a36Sopenharmony_ci	.get = param_get_int,
44062306a36Sopenharmony_ci};
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_cistatic u32 vfs_num;
44362306a36Sopenharmony_cimodule_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);
44462306a36Sopenharmony_ciMODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistatic const struct pci_device_id hisi_zip_dev_ids[] = {
44762306a36Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_PF) },
44862306a36Sopenharmony_ci	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_VF) },
44962306a36Sopenharmony_ci	{ 0, }
45062306a36Sopenharmony_ci};
45162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, hisi_zip_dev_ids);
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ciint zip_create_qps(struct hisi_qp **qps, int qp_num, int node)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	if (node == NUMA_NO_NODE)
45662306a36Sopenharmony_ci		node = cpu_to_node(smp_processor_id());
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	return hisi_qm_alloc_qps_node(&zip_devices, qp_num, 0, node, qps);
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_cibool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg)
46262306a36Sopenharmony_ci{
46362306a36Sopenharmony_ci	u32 cap_val;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci	cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val;
46662306a36Sopenharmony_ci	if ((alg & cap_val) == alg)
46762306a36Sopenharmony_ci		return true;
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	return false;
47062306a36Sopenharmony_ci}
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_cistatic int hisi_zip_set_high_perf(struct hisi_qm *qm)
47362306a36Sopenharmony_ci{
47462306a36Sopenharmony_ci	u32 val;
47562306a36Sopenharmony_ci	int ret;
47662306a36Sopenharmony_ci
47762306a36Sopenharmony_ci	val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET);
47862306a36Sopenharmony_ci	if (perf_mode == HZIP_HIGH_COMP_PERF)
47962306a36Sopenharmony_ci		val |= HZIP_HIGH_COMP_PERF;
48062306a36Sopenharmony_ci	else
48162306a36Sopenharmony_ci		val &= ~HZIP_HIGH_COMP_PERF;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	/* Set perf mode */
48462306a36Sopenharmony_ci	writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET);
48562306a36Sopenharmony_ci	ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET,
48662306a36Sopenharmony_ci					 val, val == perf_mode, HZIP_DELAY_1_US,
48762306a36Sopenharmony_ci					 HZIP_POLL_TIMEOUT_US);
48862306a36Sopenharmony_ci	if (ret)
48962306a36Sopenharmony_ci		pci_err(qm->pdev, "failed to set perf mode\n");
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	return ret;
49262306a36Sopenharmony_ci}
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_cistatic void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)
49562306a36Sopenharmony_ci{
49662306a36Sopenharmony_ci	u32 val;
49762306a36Sopenharmony_ci	int ret;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
50062306a36Sopenharmony_ci		return;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	/* Enable prefetch */
50362306a36Sopenharmony_ci	val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
50462306a36Sopenharmony_ci	val &= HZIP_PREFETCH_ENABLE;
50562306a36Sopenharmony_ci	writel(val, qm->io_base + HZIP_PREFETCH_CFG);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_PREFETCH_CFG,
50862306a36Sopenharmony_ci					 val, !(val & HZIP_SVA_PREFETCH_DISABLE),
50962306a36Sopenharmony_ci					 HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);
51062306a36Sopenharmony_ci	if (ret)
51162306a36Sopenharmony_ci		pci_err(qm->pdev, "failed to open sva prefetch\n");
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	u32 val;
51762306a36Sopenharmony_ci	int ret;
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci	if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))
52062306a36Sopenharmony_ci		return;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);
52362306a36Sopenharmony_ci	val |= HZIP_SVA_PREFETCH_DISABLE;
52462306a36Sopenharmony_ci	writel(val, qm->io_base + HZIP_PREFETCH_CFG);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_SVA_TRANS,
52762306a36Sopenharmony_ci					 val, !(val & HZIP_SVA_DISABLE_READY),
52862306a36Sopenharmony_ci					 HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);
52962306a36Sopenharmony_ci	if (ret)
53062306a36Sopenharmony_ci		pci_err(qm->pdev, "failed to close sva prefetch\n");
53162306a36Sopenharmony_ci}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_cistatic void hisi_zip_enable_clock_gate(struct hisi_qm *qm)
53462306a36Sopenharmony_ci{
53562306a36Sopenharmony_ci	u32 val;
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	if (qm->ver < QM_HW_V3)
53862306a36Sopenharmony_ci		return;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	val = readl(qm->io_base + HZIP_CLOCK_GATE_CTRL);
54162306a36Sopenharmony_ci	val |= HZIP_CLOCK_GATED_EN;
54262306a36Sopenharmony_ci	writel(val, qm->io_base + HZIP_CLOCK_GATE_CTRL);
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci	val = readl(qm->io_base + HZIP_PEH_CFG_AUTO_GATE);
54562306a36Sopenharmony_ci	val |= HZIP_PEH_CFG_AUTO_GATE_EN;
54662306a36Sopenharmony_ci	writel(val, qm->io_base + HZIP_PEH_CFG_AUTO_GATE);
54762306a36Sopenharmony_ci}
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cistatic int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)
55062306a36Sopenharmony_ci{
55162306a36Sopenharmony_ci	void __iomem *base = qm->io_base;
55262306a36Sopenharmony_ci	u32 dcomp_bm, comp_bm;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci	/* qm user domain */
55562306a36Sopenharmony_ci	writel(AXUSER_BASE, base + QM_ARUSER_M_CFG_1);
55662306a36Sopenharmony_ci	writel(ARUSER_M_CFG_ENABLE, base + QM_ARUSER_M_CFG_ENABLE);
55762306a36Sopenharmony_ci	writel(AXUSER_BASE, base + QM_AWUSER_M_CFG_1);
55862306a36Sopenharmony_ci	writel(AWUSER_M_CFG_ENABLE, base + QM_AWUSER_M_CFG_ENABLE);
55962306a36Sopenharmony_ci	writel(WUSER_M_CFG_ENABLE, base + QM_WUSER_M_CFG_ENABLE);
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	/* qm cache */
56262306a36Sopenharmony_ci	writel(AXI_M_CFG, base + QM_AXI_M_CFG);
56362306a36Sopenharmony_ci	writel(AXI_M_CFG_ENABLE, base + QM_AXI_M_CFG_ENABLE);
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	/* disable FLR triggered by BME(bus master enable) */
56662306a36Sopenharmony_ci	writel(PEH_AXUSER_CFG, base + QM_PEH_AXUSER_CFG);
56762306a36Sopenharmony_ci	writel(PEH_AXUSER_CFG_ENABLE, base + QM_PEH_AXUSER_CFG_ENABLE);
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	/* cache */
57062306a36Sopenharmony_ci	writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_ARCA_CHE_0);
57162306a36Sopenharmony_ci	writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_ARCA_CHE_1);
57262306a36Sopenharmony_ci	writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_AWCA_CHE_0);
57362306a36Sopenharmony_ci	writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_AWCA_CHE_1);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	/* user domain configurations */
57662306a36Sopenharmony_ci	writel(AXUSER_BASE, base + HZIP_BD_RUSER_32_63);
57762306a36Sopenharmony_ci	writel(AXUSER_BASE, base + HZIP_BD_WUSER_32_63);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	if (qm->use_sva && qm->ver == QM_HW_V2) {
58062306a36Sopenharmony_ci		writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_RUSER_32_63);
58162306a36Sopenharmony_ci		writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_WUSER_32_63);
58262306a36Sopenharmony_ci		writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_SGL_RUSER_32_63);
58362306a36Sopenharmony_ci	} else {
58462306a36Sopenharmony_ci		writel(AXUSER_BASE, base + HZIP_DATA_RUSER_32_63);
58562306a36Sopenharmony_ci		writel(AXUSER_BASE, base + HZIP_DATA_WUSER_32_63);
58662306a36Sopenharmony_ci		writel(AXUSER_BASE, base + HZIP_SGL_RUSER_32_63);
58762306a36Sopenharmony_ci	}
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	/* let's open all compression/decompression cores */
59062306a36Sopenharmony_ci	dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val;
59162306a36Sopenharmony_ci	comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val;
59262306a36Sopenharmony_ci	writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	/* enable sqc,cqc writeback */
59562306a36Sopenharmony_ci	writel(SQC_CACHE_ENABLE | CQC_CACHE_ENABLE | SQC_CACHE_WB_ENABLE |
59662306a36Sopenharmony_ci	       CQC_CACHE_WB_ENABLE | FIELD_PREP(SQC_CACHE_WB_THRD, 1) |
59762306a36Sopenharmony_ci	       FIELD_PREP(CQC_CACHE_WB_THRD, 1), base + QM_CACHE_CTL);
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	hisi_zip_enable_clock_gate(qm);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	return 0;
60262306a36Sopenharmony_ci}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_cistatic void hisi_zip_master_ooo_ctrl(struct hisi_qm *qm, bool enable)
60562306a36Sopenharmony_ci{
60662306a36Sopenharmony_ci	u32 val1, val2;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	val1 = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
60962306a36Sopenharmony_ci	if (enable) {
61062306a36Sopenharmony_ci		val1 |= HZIP_AXI_SHUTDOWN_ENABLE;
61162306a36Sopenharmony_ci		val2 = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
61262306a36Sopenharmony_ci				ZIP_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);
61362306a36Sopenharmony_ci	} else {
61462306a36Sopenharmony_ci		val1 &= ~HZIP_AXI_SHUTDOWN_ENABLE;
61562306a36Sopenharmony_ci		val2 = 0x0;
61662306a36Sopenharmony_ci	}
61762306a36Sopenharmony_ci
61862306a36Sopenharmony_ci	if (qm->ver > QM_HW_V2)
61962306a36Sopenharmony_ci		writel(val2, qm->io_base + HZIP_OOO_SHUTDOWN_SEL);
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	writel(val1, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
62262306a36Sopenharmony_ci}
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_cistatic void hisi_zip_hw_error_enable(struct hisi_qm *qm)
62562306a36Sopenharmony_ci{
62662306a36Sopenharmony_ci	u32 nfe, ce;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	if (qm->ver == QM_HW_V1) {
62962306a36Sopenharmony_ci		writel(HZIP_CORE_INT_MASK_ALL,
63062306a36Sopenharmony_ci		       qm->io_base + HZIP_CORE_INT_MASK_REG);
63162306a36Sopenharmony_ci		dev_info(&qm->pdev->dev, "Does not support hw error handle\n");
63262306a36Sopenharmony_ci		return;
63362306a36Sopenharmony_ci	}
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
63662306a36Sopenharmony_ci	ce = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CE_MASK_CAP, qm->cap_ver);
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	/* clear ZIP hw error source if having */
63962306a36Sopenharmony_ci	writel(ce | nfe | HZIP_CORE_INT_RAS_FE_ENB_MASK, qm->io_base + HZIP_CORE_INT_SOURCE);
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	/* configure error type */
64262306a36Sopenharmony_ci	writel(ce, qm->io_base + HZIP_CORE_INT_RAS_CE_ENB);
64362306a36Sopenharmony_ci	writel(HZIP_CORE_INT_RAS_FE_ENB_MASK, qm->io_base + HZIP_CORE_INT_RAS_FE_ENB);
64462306a36Sopenharmony_ci	writel(nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	hisi_zip_master_ooo_ctrl(qm, true);
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	/* enable ZIP hw error interrupts */
64962306a36Sopenharmony_ci	writel(0, qm->io_base + HZIP_CORE_INT_MASK_REG);
65062306a36Sopenharmony_ci}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic void hisi_zip_hw_error_disable(struct hisi_qm *qm)
65362306a36Sopenharmony_ci{
65462306a36Sopenharmony_ci	u32 nfe, ce;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	/* disable ZIP hw error interrupts */
65762306a36Sopenharmony_ci	nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
65862306a36Sopenharmony_ci	ce = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CE_MASK_CAP, qm->cap_ver);
65962306a36Sopenharmony_ci	writel(ce | nfe | HZIP_CORE_INT_RAS_FE_ENB_MASK, qm->io_base + HZIP_CORE_INT_MASK_REG);
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	hisi_zip_master_ooo_ctrl(qm, false);
66262306a36Sopenharmony_ci}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_cistatic inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file)
66562306a36Sopenharmony_ci{
66662306a36Sopenharmony_ci	struct hisi_zip *hisi_zip = file->ctrl->hisi_zip;
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_ci	return &hisi_zip->qm;
66962306a36Sopenharmony_ci}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_cistatic u32 clear_enable_read(struct hisi_qm *qm)
67262306a36Sopenharmony_ci{
67362306a36Sopenharmony_ci	return readl(qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE) &
67462306a36Sopenharmony_ci		     HZIP_SOFT_CTRL_CNT_CLR_CE_BIT;
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_cistatic int clear_enable_write(struct hisi_qm *qm, u32 val)
67862306a36Sopenharmony_ci{
67962306a36Sopenharmony_ci	u32 tmp;
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_ci	if (val != 1 && val != 0)
68262306a36Sopenharmony_ci		return -EINVAL;
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	tmp = (readl(qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE) &
68562306a36Sopenharmony_ci	       ~HZIP_SOFT_CTRL_CNT_CLR_CE_BIT) | val;
68662306a36Sopenharmony_ci	writel(tmp, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	return  0;
68962306a36Sopenharmony_ci}
69062306a36Sopenharmony_ci
69162306a36Sopenharmony_cistatic ssize_t hisi_zip_ctrl_debug_read(struct file *filp, char __user *buf,
69262306a36Sopenharmony_ci					size_t count, loff_t *pos)
69362306a36Sopenharmony_ci{
69462306a36Sopenharmony_ci	struct ctrl_debug_file *file = filp->private_data;
69562306a36Sopenharmony_ci	struct hisi_qm *qm = file_to_qm(file);
69662306a36Sopenharmony_ci	char tbuf[HZIP_BUF_SIZE];
69762306a36Sopenharmony_ci	u32 val;
69862306a36Sopenharmony_ci	int ret;
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	ret = hisi_qm_get_dfx_access(qm);
70162306a36Sopenharmony_ci	if (ret)
70262306a36Sopenharmony_ci		return ret;
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci	spin_lock_irq(&file->lock);
70562306a36Sopenharmony_ci	switch (file->index) {
70662306a36Sopenharmony_ci	case HZIP_CLEAR_ENABLE:
70762306a36Sopenharmony_ci		val = clear_enable_read(qm);
70862306a36Sopenharmony_ci		break;
70962306a36Sopenharmony_ci	default:
71062306a36Sopenharmony_ci		goto err_input;
71162306a36Sopenharmony_ci	}
71262306a36Sopenharmony_ci	spin_unlock_irq(&file->lock);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	hisi_qm_put_dfx_access(qm);
71562306a36Sopenharmony_ci	ret = scnprintf(tbuf, sizeof(tbuf), "%u\n", val);
71662306a36Sopenharmony_ci	return simple_read_from_buffer(buf, count, pos, tbuf, ret);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cierr_input:
71962306a36Sopenharmony_ci	spin_unlock_irq(&file->lock);
72062306a36Sopenharmony_ci	hisi_qm_put_dfx_access(qm);
72162306a36Sopenharmony_ci	return -EINVAL;
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic ssize_t hisi_zip_ctrl_debug_write(struct file *filp,
72562306a36Sopenharmony_ci					 const char __user *buf,
72662306a36Sopenharmony_ci					 size_t count, loff_t *pos)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	struct ctrl_debug_file *file = filp->private_data;
72962306a36Sopenharmony_ci	struct hisi_qm *qm = file_to_qm(file);
73062306a36Sopenharmony_ci	char tbuf[HZIP_BUF_SIZE];
73162306a36Sopenharmony_ci	unsigned long val;
73262306a36Sopenharmony_ci	int len, ret;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	if (*pos != 0)
73562306a36Sopenharmony_ci		return 0;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	if (count >= HZIP_BUF_SIZE)
73862306a36Sopenharmony_ci		return -ENOSPC;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci	len = simple_write_to_buffer(tbuf, HZIP_BUF_SIZE - 1, pos, buf, count);
74162306a36Sopenharmony_ci	if (len < 0)
74262306a36Sopenharmony_ci		return len;
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_ci	tbuf[len] = '\0';
74562306a36Sopenharmony_ci	ret = kstrtoul(tbuf, 0, &val);
74662306a36Sopenharmony_ci	if (ret)
74762306a36Sopenharmony_ci		return ret;
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	ret = hisi_qm_get_dfx_access(qm);
75062306a36Sopenharmony_ci	if (ret)
75162306a36Sopenharmony_ci		return ret;
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci	spin_lock_irq(&file->lock);
75462306a36Sopenharmony_ci	switch (file->index) {
75562306a36Sopenharmony_ci	case HZIP_CLEAR_ENABLE:
75662306a36Sopenharmony_ci		ret = clear_enable_write(qm, val);
75762306a36Sopenharmony_ci		if (ret)
75862306a36Sopenharmony_ci			goto err_input;
75962306a36Sopenharmony_ci		break;
76062306a36Sopenharmony_ci	default:
76162306a36Sopenharmony_ci		ret = -EINVAL;
76262306a36Sopenharmony_ci		goto err_input;
76362306a36Sopenharmony_ci	}
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	ret = count;
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_cierr_input:
76862306a36Sopenharmony_ci	spin_unlock_irq(&file->lock);
76962306a36Sopenharmony_ci	hisi_qm_put_dfx_access(qm);
77062306a36Sopenharmony_ci	return ret;
77162306a36Sopenharmony_ci}
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_cistatic const struct file_operations ctrl_debug_fops = {
77462306a36Sopenharmony_ci	.owner = THIS_MODULE,
77562306a36Sopenharmony_ci	.open = simple_open,
77662306a36Sopenharmony_ci	.read = hisi_zip_ctrl_debug_read,
77762306a36Sopenharmony_ci	.write = hisi_zip_ctrl_debug_write,
77862306a36Sopenharmony_ci};
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_cistatic int zip_debugfs_atomic64_set(void *data, u64 val)
78162306a36Sopenharmony_ci{
78262306a36Sopenharmony_ci	if (val)
78362306a36Sopenharmony_ci		return -EINVAL;
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	atomic64_set((atomic64_t *)data, 0);
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci	return 0;
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic int zip_debugfs_atomic64_get(void *data, u64 *val)
79162306a36Sopenharmony_ci{
79262306a36Sopenharmony_ci	*val = atomic64_read((atomic64_t *)data);
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci	return 0;
79562306a36Sopenharmony_ci}
79662306a36Sopenharmony_ci
79762306a36Sopenharmony_ciDEFINE_DEBUGFS_ATTRIBUTE(zip_atomic64_ops, zip_debugfs_atomic64_get,
79862306a36Sopenharmony_ci			 zip_debugfs_atomic64_set, "%llu\n");
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_cistatic int hisi_zip_regs_show(struct seq_file *s, void *unused)
80162306a36Sopenharmony_ci{
80262306a36Sopenharmony_ci	hisi_qm_regs_dump(s, s->private);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	return 0;
80562306a36Sopenharmony_ci}
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(hisi_zip_regs);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_cistatic int hisi_zip_core_debug_init(struct hisi_qm *qm)
81062306a36Sopenharmony_ci{
81162306a36Sopenharmony_ci	u32 zip_core_num, zip_comp_core_num;
81262306a36Sopenharmony_ci	struct device *dev = &qm->pdev->dev;
81362306a36Sopenharmony_ci	struct debugfs_regset32 *regset;
81462306a36Sopenharmony_ci	struct dentry *tmp_d;
81562306a36Sopenharmony_ci	char buf[HZIP_BUF_SIZE];
81662306a36Sopenharmony_ci	int i;
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
81962306a36Sopenharmony_ci	zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	for (i = 0; i < zip_core_num; i++) {
82262306a36Sopenharmony_ci		if (i < zip_comp_core_num)
82362306a36Sopenharmony_ci			scnprintf(buf, sizeof(buf), "comp_core%d", i);
82462306a36Sopenharmony_ci		else
82562306a36Sopenharmony_ci			scnprintf(buf, sizeof(buf), "decomp_core%d",
82662306a36Sopenharmony_ci				  i - zip_comp_core_num);
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci		regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
82962306a36Sopenharmony_ci		if (!regset)
83062306a36Sopenharmony_ci			return -ENOENT;
83162306a36Sopenharmony_ci
83262306a36Sopenharmony_ci		regset->regs = hzip_dfx_regs;
83362306a36Sopenharmony_ci		regset->nregs = ARRAY_SIZE(hzip_dfx_regs);
83462306a36Sopenharmony_ci		regset->base = qm->io_base + core_offsets[i];
83562306a36Sopenharmony_ci		regset->dev = dev;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci		tmp_d = debugfs_create_dir(buf, qm->debug.debug_root);
83862306a36Sopenharmony_ci		debugfs_create_file("regs", 0444, tmp_d, regset,
83962306a36Sopenharmony_ci				    &hisi_zip_regs_fops);
84062306a36Sopenharmony_ci	}
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	return 0;
84362306a36Sopenharmony_ci}
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_cistatic void hisi_zip_dfx_debug_init(struct hisi_qm *qm)
84662306a36Sopenharmony_ci{
84762306a36Sopenharmony_ci	struct dfx_diff_registers *hzip_regs = qm->debug.acc_diff_regs;
84862306a36Sopenharmony_ci	struct hisi_zip *zip = container_of(qm, struct hisi_zip, qm);
84962306a36Sopenharmony_ci	struct hisi_zip_dfx *dfx = &zip->dfx;
85062306a36Sopenharmony_ci	struct dentry *tmp_dir;
85162306a36Sopenharmony_ci	void *data;
85262306a36Sopenharmony_ci	int i;
85362306a36Sopenharmony_ci
85462306a36Sopenharmony_ci	tmp_dir = debugfs_create_dir("zip_dfx", qm->debug.debug_root);
85562306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(zip_dfx_files); i++) {
85662306a36Sopenharmony_ci		data = (atomic64_t *)((uintptr_t)dfx + zip_dfx_files[i].offset);
85762306a36Sopenharmony_ci		debugfs_create_file(zip_dfx_files[i].name,
85862306a36Sopenharmony_ci				    0644, tmp_dir, data,
85962306a36Sopenharmony_ci				    &zip_atomic64_ops);
86062306a36Sopenharmony_ci	}
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF && hzip_regs)
86362306a36Sopenharmony_ci		debugfs_create_file("diff_regs", 0444, tmp_dir,
86462306a36Sopenharmony_ci				      qm, &hzip_diff_regs_fops);
86562306a36Sopenharmony_ci}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_cistatic int hisi_zip_ctrl_debug_init(struct hisi_qm *qm)
86862306a36Sopenharmony_ci{
86962306a36Sopenharmony_ci	struct hisi_zip *zip = container_of(qm, struct hisi_zip, qm);
87062306a36Sopenharmony_ci	int i;
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci	for (i = HZIP_CLEAR_ENABLE; i < HZIP_DEBUG_FILE_NUM; i++) {
87362306a36Sopenharmony_ci		spin_lock_init(&zip->ctrl->files[i].lock);
87462306a36Sopenharmony_ci		zip->ctrl->files[i].ctrl = zip->ctrl;
87562306a36Sopenharmony_ci		zip->ctrl->files[i].index = i;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci		debugfs_create_file(ctrl_debug_file_name[i], 0600,
87862306a36Sopenharmony_ci				    qm->debug.debug_root,
87962306a36Sopenharmony_ci				    zip->ctrl->files + i,
88062306a36Sopenharmony_ci				    &ctrl_debug_fops);
88162306a36Sopenharmony_ci	}
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	return hisi_zip_core_debug_init(qm);
88462306a36Sopenharmony_ci}
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_cistatic int hisi_zip_debugfs_init(struct hisi_qm *qm)
88762306a36Sopenharmony_ci{
88862306a36Sopenharmony_ci	struct device *dev = &qm->pdev->dev;
88962306a36Sopenharmony_ci	struct dentry *dev_d;
89062306a36Sopenharmony_ci	int ret;
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	dev_d = debugfs_create_dir(dev_name(dev), hzip_debugfs_root);
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci	qm->debug.sqe_mask_offset = HZIP_SQE_MASK_OFFSET;
89562306a36Sopenharmony_ci	qm->debug.sqe_mask_len = HZIP_SQE_MASK_LEN;
89662306a36Sopenharmony_ci	qm->debug.debug_root = dev_d;
89762306a36Sopenharmony_ci	ret = hisi_qm_regs_debugfs_init(qm, hzip_diff_regs, ARRAY_SIZE(hzip_diff_regs));
89862306a36Sopenharmony_ci	if (ret) {
89962306a36Sopenharmony_ci		dev_warn(dev, "Failed to init ZIP diff regs!\n");
90062306a36Sopenharmony_ci		goto debugfs_remove;
90162306a36Sopenharmony_ci	}
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	hisi_qm_debug_init(qm);
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF) {
90662306a36Sopenharmony_ci		ret = hisi_zip_ctrl_debug_init(qm);
90762306a36Sopenharmony_ci		if (ret)
90862306a36Sopenharmony_ci			goto failed_to_create;
90962306a36Sopenharmony_ci	}
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	hisi_zip_dfx_debug_init(qm);
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci	return 0;
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_cifailed_to_create:
91662306a36Sopenharmony_ci	hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs));
91762306a36Sopenharmony_cidebugfs_remove:
91862306a36Sopenharmony_ci	debugfs_remove_recursive(hzip_debugfs_root);
91962306a36Sopenharmony_ci	return ret;
92062306a36Sopenharmony_ci}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci/* hisi_zip_debug_regs_clear() - clear the zip debug regs */
92362306a36Sopenharmony_cistatic void hisi_zip_debug_regs_clear(struct hisi_qm *qm)
92462306a36Sopenharmony_ci{
92562306a36Sopenharmony_ci	int i, j;
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	/* enable register read_clear bit */
92862306a36Sopenharmony_ci	writel(HZIP_RD_CNT_CLR_CE_EN, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);
92962306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(core_offsets); i++)
93062306a36Sopenharmony_ci		for (j = 0; j < ARRAY_SIZE(hzip_dfx_regs); j++)
93162306a36Sopenharmony_ci			readl(qm->io_base + core_offsets[i] +
93262306a36Sopenharmony_ci			      hzip_dfx_regs[j].offset);
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci	/* disable register read_clear bit */
93562306a36Sopenharmony_ci	writel(0x0, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	hisi_qm_debug_regs_clear(qm);
93862306a36Sopenharmony_ci}
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_cistatic void hisi_zip_debugfs_exit(struct hisi_qm *qm)
94162306a36Sopenharmony_ci{
94262306a36Sopenharmony_ci	hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs));
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	debugfs_remove_recursive(qm->debug.debug_root);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF) {
94762306a36Sopenharmony_ci		hisi_zip_debug_regs_clear(qm);
94862306a36Sopenharmony_ci		qm->debug.curr_qm_qp_num = 0;
94962306a36Sopenharmony_ci	}
95062306a36Sopenharmony_ci}
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_cistatic int hisi_zip_show_last_regs_init(struct hisi_qm *qm)
95362306a36Sopenharmony_ci{
95462306a36Sopenharmony_ci	int core_dfx_regs_num =  ARRAY_SIZE(hzip_dump_dfx_regs);
95562306a36Sopenharmony_ci	int com_dfx_regs_num = ARRAY_SIZE(hzip_com_dfx_regs);
95662306a36Sopenharmony_ci	struct qm_debug *debug = &qm->debug;
95762306a36Sopenharmony_ci	void __iomem *io_base;
95862306a36Sopenharmony_ci	u32 zip_core_num;
95962306a36Sopenharmony_ci	int i, j, idx;
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci	zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci	debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num,
96462306a36Sopenharmony_ci				    sizeof(unsigned int), GFP_KERNEL);
96562306a36Sopenharmony_ci	if (!debug->last_words)
96662306a36Sopenharmony_ci		return -ENOMEM;
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	for (i = 0; i < com_dfx_regs_num; i++) {
96962306a36Sopenharmony_ci		io_base = qm->io_base + hzip_com_dfx_regs[i].offset;
97062306a36Sopenharmony_ci		debug->last_words[i] = readl_relaxed(io_base);
97162306a36Sopenharmony_ci	}
97262306a36Sopenharmony_ci
97362306a36Sopenharmony_ci	for (i = 0; i < zip_core_num; i++) {
97462306a36Sopenharmony_ci		io_base = qm->io_base + core_offsets[i];
97562306a36Sopenharmony_ci		for (j = 0; j < core_dfx_regs_num; j++) {
97662306a36Sopenharmony_ci			idx = com_dfx_regs_num + i * core_dfx_regs_num + j;
97762306a36Sopenharmony_ci			debug->last_words[idx] = readl_relaxed(
97862306a36Sopenharmony_ci				io_base + hzip_dump_dfx_regs[j].offset);
97962306a36Sopenharmony_ci		}
98062306a36Sopenharmony_ci	}
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	return 0;
98362306a36Sopenharmony_ci}
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_cistatic void hisi_zip_show_last_regs_uninit(struct hisi_qm *qm)
98662306a36Sopenharmony_ci{
98762306a36Sopenharmony_ci	struct qm_debug *debug = &qm->debug;
98862306a36Sopenharmony_ci
98962306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_VF || !debug->last_words)
99062306a36Sopenharmony_ci		return;
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	kfree(debug->last_words);
99362306a36Sopenharmony_ci	debug->last_words = NULL;
99462306a36Sopenharmony_ci}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_cistatic void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm)
99762306a36Sopenharmony_ci{
99862306a36Sopenharmony_ci	int core_dfx_regs_num =  ARRAY_SIZE(hzip_dump_dfx_regs);
99962306a36Sopenharmony_ci	int com_dfx_regs_num = ARRAY_SIZE(hzip_com_dfx_regs);
100062306a36Sopenharmony_ci	u32 zip_core_num, zip_comp_core_num;
100162306a36Sopenharmony_ci	struct qm_debug *debug = &qm->debug;
100262306a36Sopenharmony_ci	char buf[HZIP_BUF_SIZE];
100362306a36Sopenharmony_ci	void __iomem *base;
100462306a36Sopenharmony_ci	int i, j, idx;
100562306a36Sopenharmony_ci	u32 val;
100662306a36Sopenharmony_ci
100762306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_VF || !debug->last_words)
100862306a36Sopenharmony_ci		return;
100962306a36Sopenharmony_ci
101062306a36Sopenharmony_ci	for (i = 0; i < com_dfx_regs_num; i++) {
101162306a36Sopenharmony_ci		val = readl_relaxed(qm->io_base + hzip_com_dfx_regs[i].offset);
101262306a36Sopenharmony_ci		if (debug->last_words[i] != val)
101362306a36Sopenharmony_ci			pci_info(qm->pdev, "com_dfx: %s \t= 0x%08x => 0x%08x\n",
101462306a36Sopenharmony_ci				 hzip_com_dfx_regs[i].name, debug->last_words[i], val);
101562306a36Sopenharmony_ci	}
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val;
101862306a36Sopenharmony_ci	zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val;
101962306a36Sopenharmony_ci
102062306a36Sopenharmony_ci	for (i = 0; i < zip_core_num; i++) {
102162306a36Sopenharmony_ci		if (i < zip_comp_core_num)
102262306a36Sopenharmony_ci			scnprintf(buf, sizeof(buf), "Comp_core-%d", i);
102362306a36Sopenharmony_ci		else
102462306a36Sopenharmony_ci			scnprintf(buf, sizeof(buf), "Decomp_core-%d",
102562306a36Sopenharmony_ci				  i - zip_comp_core_num);
102662306a36Sopenharmony_ci		base = qm->io_base + core_offsets[i];
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci		pci_info(qm->pdev, "==>%s:\n", buf);
102962306a36Sopenharmony_ci		/* dump last word for dfx regs during control resetting */
103062306a36Sopenharmony_ci		for (j = 0; j < core_dfx_regs_num; j++) {
103162306a36Sopenharmony_ci			idx = com_dfx_regs_num + i * core_dfx_regs_num + j;
103262306a36Sopenharmony_ci			val = readl_relaxed(base + hzip_dump_dfx_regs[j].offset);
103362306a36Sopenharmony_ci			if (debug->last_words[idx] != val)
103462306a36Sopenharmony_ci				pci_info(qm->pdev, "%s \t= 0x%08x => 0x%08x\n",
103562306a36Sopenharmony_ci					 hzip_dump_dfx_regs[j].name,
103662306a36Sopenharmony_ci					 debug->last_words[idx], val);
103762306a36Sopenharmony_ci		}
103862306a36Sopenharmony_ci	}
103962306a36Sopenharmony_ci}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic void hisi_zip_log_hw_error(struct hisi_qm *qm, u32 err_sts)
104262306a36Sopenharmony_ci{
104362306a36Sopenharmony_ci	const struct hisi_zip_hw_error *err = zip_hw_error;
104462306a36Sopenharmony_ci	struct device *dev = &qm->pdev->dev;
104562306a36Sopenharmony_ci	u32 err_val;
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	while (err->msg) {
104862306a36Sopenharmony_ci		if (err->int_msk & err_sts) {
104962306a36Sopenharmony_ci			dev_err(dev, "%s [error status=0x%x] found\n",
105062306a36Sopenharmony_ci				err->msg, err->int_msk);
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci			if (err->int_msk & HZIP_CORE_INT_STATUS_M_ECC) {
105362306a36Sopenharmony_ci				err_val = readl(qm->io_base +
105462306a36Sopenharmony_ci						HZIP_CORE_SRAM_ECC_ERR_INFO);
105562306a36Sopenharmony_ci				dev_err(dev, "hisi-zip multi ecc sram num=0x%x\n",
105662306a36Sopenharmony_ci					((err_val >>
105762306a36Sopenharmony_ci					HZIP_SRAM_ECC_ERR_NUM_SHIFT) & 0xFF));
105862306a36Sopenharmony_ci			}
105962306a36Sopenharmony_ci		}
106062306a36Sopenharmony_ci		err++;
106162306a36Sopenharmony_ci	}
106262306a36Sopenharmony_ci}
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_cistatic u32 hisi_zip_get_hw_err_status(struct hisi_qm *qm)
106562306a36Sopenharmony_ci{
106662306a36Sopenharmony_ci	return readl(qm->io_base + HZIP_CORE_INT_STATUS);
106762306a36Sopenharmony_ci}
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_cistatic void hisi_zip_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
107062306a36Sopenharmony_ci{
107162306a36Sopenharmony_ci	u32 nfe;
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci	writel(err_sts, qm->io_base + HZIP_CORE_INT_SOURCE);
107462306a36Sopenharmony_ci	nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
107562306a36Sopenharmony_ci	writel(nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
107662306a36Sopenharmony_ci}
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_cistatic void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm)
107962306a36Sopenharmony_ci{
108062306a36Sopenharmony_ci	u32 val;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_ci	writel(val & ~HZIP_AXI_SHUTDOWN_ENABLE,
108562306a36Sopenharmony_ci	       qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci	writel(val | HZIP_AXI_SHUTDOWN_ENABLE,
108862306a36Sopenharmony_ci	       qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);
108962306a36Sopenharmony_ci}
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_cistatic void hisi_zip_close_axi_master_ooo(struct hisi_qm *qm)
109262306a36Sopenharmony_ci{
109362306a36Sopenharmony_ci	u32 nfe_enb;
109462306a36Sopenharmony_ci
109562306a36Sopenharmony_ci	/* Disable ECC Mbit error report. */
109662306a36Sopenharmony_ci	nfe_enb = readl(qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
109762306a36Sopenharmony_ci	writel(nfe_enb & ~HZIP_CORE_INT_STATUS_M_ECC,
109862306a36Sopenharmony_ci	       qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_ci	/* Inject zip ECC Mbit error to block master ooo. */
110162306a36Sopenharmony_ci	writel(HZIP_CORE_INT_STATUS_M_ECC,
110262306a36Sopenharmony_ci	       qm->io_base + HZIP_CORE_INT_SET);
110362306a36Sopenharmony_ci}
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_cistatic void hisi_zip_err_info_init(struct hisi_qm *qm)
110662306a36Sopenharmony_ci{
110762306a36Sopenharmony_ci	struct hisi_qm_err_info *err_info = &qm->err_info;
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	err_info->fe = HZIP_CORE_INT_RAS_FE_ENB_MASK;
111062306a36Sopenharmony_ci	err_info->ce = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_QM_CE_MASK_CAP, qm->cap_ver);
111162306a36Sopenharmony_ci	err_info->nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
111262306a36Sopenharmony_ci					    ZIP_QM_NFE_MASK_CAP, qm->cap_ver);
111362306a36Sopenharmony_ci	err_info->ecc_2bits_mask = HZIP_CORE_INT_STATUS_M_ECC;
111462306a36Sopenharmony_ci	err_info->qm_shutdown_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
111562306a36Sopenharmony_ci							 ZIP_QM_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);
111662306a36Sopenharmony_ci	err_info->dev_shutdown_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
111762306a36Sopenharmony_ci							  ZIP_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);
111862306a36Sopenharmony_ci	err_info->qm_reset_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
111962306a36Sopenharmony_ci						      ZIP_QM_RESET_MASK_CAP, qm->cap_ver);
112062306a36Sopenharmony_ci	err_info->dev_reset_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
112162306a36Sopenharmony_ci						       ZIP_RESET_MASK_CAP, qm->cap_ver);
112262306a36Sopenharmony_ci	err_info->msi_wr_port = HZIP_WR_PORT;
112362306a36Sopenharmony_ci	err_info->acpi_rst = "ZRST";
112462306a36Sopenharmony_ci}
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_cistatic const struct hisi_qm_err_ini hisi_zip_err_ini = {
112762306a36Sopenharmony_ci	.hw_init		= hisi_zip_set_user_domain_and_cache,
112862306a36Sopenharmony_ci	.hw_err_enable		= hisi_zip_hw_error_enable,
112962306a36Sopenharmony_ci	.hw_err_disable		= hisi_zip_hw_error_disable,
113062306a36Sopenharmony_ci	.get_dev_hw_err_status	= hisi_zip_get_hw_err_status,
113162306a36Sopenharmony_ci	.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status,
113262306a36Sopenharmony_ci	.log_dev_hw_err		= hisi_zip_log_hw_error,
113362306a36Sopenharmony_ci	.open_axi_master_ooo	= hisi_zip_open_axi_master_ooo,
113462306a36Sopenharmony_ci	.close_axi_master_ooo	= hisi_zip_close_axi_master_ooo,
113562306a36Sopenharmony_ci	.open_sva_prefetch	= hisi_zip_open_sva_prefetch,
113662306a36Sopenharmony_ci	.close_sva_prefetch	= hisi_zip_close_sva_prefetch,
113762306a36Sopenharmony_ci	.show_last_dfx_regs	= hisi_zip_show_last_dfx_regs,
113862306a36Sopenharmony_ci	.err_info_init		= hisi_zip_err_info_init,
113962306a36Sopenharmony_ci};
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_cistatic int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
114262306a36Sopenharmony_ci{
114362306a36Sopenharmony_ci	struct hisi_qm *qm = &hisi_zip->qm;
114462306a36Sopenharmony_ci	struct hisi_zip_ctrl *ctrl;
114562306a36Sopenharmony_ci	int ret;
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_ci	ctrl = devm_kzalloc(&qm->pdev->dev, sizeof(*ctrl), GFP_KERNEL);
114862306a36Sopenharmony_ci	if (!ctrl)
114962306a36Sopenharmony_ci		return -ENOMEM;
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	hisi_zip->ctrl = ctrl;
115262306a36Sopenharmony_ci	ctrl->hisi_zip = hisi_zip;
115362306a36Sopenharmony_ci	qm->err_ini = &hisi_zip_err_ini;
115462306a36Sopenharmony_ci	qm->err_ini->err_info_init(qm);
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci	ret = hisi_zip_set_user_domain_and_cache(qm);
115762306a36Sopenharmony_ci	if (ret)
115862306a36Sopenharmony_ci		return ret;
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ci	ret = hisi_zip_set_high_perf(qm);
116162306a36Sopenharmony_ci	if (ret)
116262306a36Sopenharmony_ci		return ret;
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	hisi_zip_open_sva_prefetch(qm);
116562306a36Sopenharmony_ci	hisi_qm_dev_err_init(qm);
116662306a36Sopenharmony_ci	hisi_zip_debug_regs_clear(qm);
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	ret = hisi_zip_show_last_regs_init(qm);
116962306a36Sopenharmony_ci	if (ret)
117062306a36Sopenharmony_ci		pci_err(qm->pdev, "Failed to init last word regs!\n");
117162306a36Sopenharmony_ci
117262306a36Sopenharmony_ci	return ret;
117362306a36Sopenharmony_ci}
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_cistatic int zip_pre_store_cap_reg(struct hisi_qm *qm)
117662306a36Sopenharmony_ci{
117762306a36Sopenharmony_ci	struct hisi_qm_cap_record *zip_cap;
117862306a36Sopenharmony_ci	struct pci_dev *pdev = qm->pdev;
117962306a36Sopenharmony_ci	size_t i, size;
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	size = ARRAY_SIZE(zip_pre_store_caps);
118262306a36Sopenharmony_ci	zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL);
118362306a36Sopenharmony_ci	if (!zip_cap)
118462306a36Sopenharmony_ci		return -ENOMEM;
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
118762306a36Sopenharmony_ci		zip_cap[i].type = zip_pre_store_caps[i];
118862306a36Sopenharmony_ci		zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info,
118962306a36Sopenharmony_ci				     zip_pre_store_caps[i], qm->cap_ver);
119062306a36Sopenharmony_ci	}
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	qm->cap_tables.dev_cap_table = zip_cap;
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	return 0;
119562306a36Sopenharmony_ci}
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_cistatic int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
119862306a36Sopenharmony_ci{
119962306a36Sopenharmony_ci	u64 alg_msk;
120062306a36Sopenharmony_ci	int ret;
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	qm->pdev = pdev;
120362306a36Sopenharmony_ci	qm->ver = pdev->revision;
120462306a36Sopenharmony_ci	qm->mode = uacce_mode;
120562306a36Sopenharmony_ci	qm->sqe_size = HZIP_SQE_SIZE;
120662306a36Sopenharmony_ci	qm->dev_name = hisi_zip_name;
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_ZIP_PF) ?
120962306a36Sopenharmony_ci			QM_HW_PF : QM_HW_VF;
121062306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF) {
121162306a36Sopenharmony_ci		qm->qp_base = HZIP_PF_DEF_Q_BASE;
121262306a36Sopenharmony_ci		qm->qp_num = pf_q_num;
121362306a36Sopenharmony_ci		qm->debug.curr_qm_qp_num = pf_q_num;
121462306a36Sopenharmony_ci		qm->qm_list = &zip_devices;
121562306a36Sopenharmony_ci		if (pf_q_num_flag)
121662306a36Sopenharmony_ci			set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
121762306a36Sopenharmony_ci	} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
121862306a36Sopenharmony_ci		/*
121962306a36Sopenharmony_ci		 * have no way to get qm configure in VM in v1 hardware,
122062306a36Sopenharmony_ci		 * so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force
122162306a36Sopenharmony_ci		 * to trigger only one VF in v1 hardware.
122262306a36Sopenharmony_ci		 *
122362306a36Sopenharmony_ci		 * v2 hardware has no such problem.
122462306a36Sopenharmony_ci		 */
122562306a36Sopenharmony_ci		qm->qp_base = HZIP_PF_DEF_Q_NUM;
122662306a36Sopenharmony_ci		qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;
122762306a36Sopenharmony_ci	}
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	ret = hisi_qm_init(qm);
123062306a36Sopenharmony_ci	if (ret) {
123162306a36Sopenharmony_ci		pci_err(qm->pdev, "Failed to init zip qm configures!\n");
123262306a36Sopenharmony_ci		return ret;
123362306a36Sopenharmony_ci	}
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci	/* Fetch and save the value of capability registers */
123662306a36Sopenharmony_ci	ret = zip_pre_store_cap_reg(qm);
123762306a36Sopenharmony_ci	if (ret) {
123862306a36Sopenharmony_ci		pci_err(qm->pdev, "Failed to pre-store capability registers!\n");
123962306a36Sopenharmony_ci		hisi_qm_uninit(qm);
124062306a36Sopenharmony_ci		return ret;
124162306a36Sopenharmony_ci	}
124262306a36Sopenharmony_ci
124362306a36Sopenharmony_ci	alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val;
124462306a36Sopenharmony_ci	ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs));
124562306a36Sopenharmony_ci	if (ret) {
124662306a36Sopenharmony_ci		pci_err(qm->pdev, "Failed to set zip algs!\n");
124762306a36Sopenharmony_ci		hisi_qm_uninit(qm);
124862306a36Sopenharmony_ci	}
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	return ret;
125162306a36Sopenharmony_ci}
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_cistatic void hisi_zip_qm_uninit(struct hisi_qm *qm)
125462306a36Sopenharmony_ci{
125562306a36Sopenharmony_ci	hisi_qm_uninit(qm);
125662306a36Sopenharmony_ci}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_cistatic int hisi_zip_probe_init(struct hisi_zip *hisi_zip)
125962306a36Sopenharmony_ci{
126062306a36Sopenharmony_ci	u32 type_rate = HZIP_SHAPER_RATE_COMPRESS;
126162306a36Sopenharmony_ci	struct hisi_qm *qm = &hisi_zip->qm;
126262306a36Sopenharmony_ci	int ret;
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF) {
126562306a36Sopenharmony_ci		ret = hisi_zip_pf_probe_init(hisi_zip);
126662306a36Sopenharmony_ci		if (ret)
126762306a36Sopenharmony_ci			return ret;
126862306a36Sopenharmony_ci		/* enable shaper type 0 */
126962306a36Sopenharmony_ci		if (qm->ver >= QM_HW_V3) {
127062306a36Sopenharmony_ci			type_rate |= QM_SHAPER_ENABLE;
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ci			/* ZIP need to enable shaper type 1 */
127362306a36Sopenharmony_ci			type_rate |= HZIP_SHAPER_RATE_DECOMPRESS << QM_SHAPER_TYPE1_OFFSET;
127462306a36Sopenharmony_ci			qm->type_rate = type_rate;
127562306a36Sopenharmony_ci		}
127662306a36Sopenharmony_ci	}
127762306a36Sopenharmony_ci
127862306a36Sopenharmony_ci	return 0;
127962306a36Sopenharmony_ci}
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_cistatic int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
128262306a36Sopenharmony_ci{
128362306a36Sopenharmony_ci	struct hisi_zip *hisi_zip;
128462306a36Sopenharmony_ci	struct hisi_qm *qm;
128562306a36Sopenharmony_ci	int ret;
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci	hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL);
128862306a36Sopenharmony_ci	if (!hisi_zip)
128962306a36Sopenharmony_ci		return -ENOMEM;
129062306a36Sopenharmony_ci
129162306a36Sopenharmony_ci	qm = &hisi_zip->qm;
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci	ret = hisi_zip_qm_init(qm, pdev);
129462306a36Sopenharmony_ci	if (ret) {
129562306a36Sopenharmony_ci		pci_err(pdev, "Failed to init ZIP QM (%d)!\n", ret);
129662306a36Sopenharmony_ci		return ret;
129762306a36Sopenharmony_ci	}
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ci	ret = hisi_zip_probe_init(hisi_zip);
130062306a36Sopenharmony_ci	if (ret) {
130162306a36Sopenharmony_ci		pci_err(pdev, "Failed to probe (%d)!\n", ret);
130262306a36Sopenharmony_ci		goto err_qm_uninit;
130362306a36Sopenharmony_ci	}
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_ci	ret = hisi_qm_start(qm);
130662306a36Sopenharmony_ci	if (ret)
130762306a36Sopenharmony_ci		goto err_dev_err_uninit;
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	ret = hisi_zip_debugfs_init(qm);
131062306a36Sopenharmony_ci	if (ret)
131162306a36Sopenharmony_ci		pci_err(pdev, "failed to init debugfs (%d)!\n", ret);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci	ret = hisi_qm_alg_register(qm, &zip_devices);
131462306a36Sopenharmony_ci	if (ret < 0) {
131562306a36Sopenharmony_ci		pci_err(pdev, "failed to register driver to crypto!\n");
131662306a36Sopenharmony_ci		goto err_qm_stop;
131762306a36Sopenharmony_ci	}
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	if (qm->uacce) {
132062306a36Sopenharmony_ci		ret = uacce_register(qm->uacce);
132162306a36Sopenharmony_ci		if (ret) {
132262306a36Sopenharmony_ci			pci_err(pdev, "failed to register uacce (%d)!\n", ret);
132362306a36Sopenharmony_ci			goto err_qm_alg_unregister;
132462306a36Sopenharmony_ci		}
132562306a36Sopenharmony_ci	}
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF && vfs_num > 0) {
132862306a36Sopenharmony_ci		ret = hisi_qm_sriov_enable(pdev, vfs_num);
132962306a36Sopenharmony_ci		if (ret < 0)
133062306a36Sopenharmony_ci			goto err_qm_alg_unregister;
133162306a36Sopenharmony_ci	}
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	hisi_qm_pm_init(qm);
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ci	return 0;
133662306a36Sopenharmony_ci
133762306a36Sopenharmony_cierr_qm_alg_unregister:
133862306a36Sopenharmony_ci	hisi_qm_alg_unregister(qm, &zip_devices);
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_cierr_qm_stop:
134162306a36Sopenharmony_ci	hisi_zip_debugfs_exit(qm);
134262306a36Sopenharmony_ci	hisi_qm_stop(qm, QM_NORMAL);
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_cierr_dev_err_uninit:
134562306a36Sopenharmony_ci	hisi_zip_show_last_regs_uninit(qm);
134662306a36Sopenharmony_ci	hisi_qm_dev_err_uninit(qm);
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_cierr_qm_uninit:
134962306a36Sopenharmony_ci	hisi_zip_qm_uninit(qm);
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	return ret;
135262306a36Sopenharmony_ci}
135362306a36Sopenharmony_ci
135462306a36Sopenharmony_cistatic void hisi_zip_remove(struct pci_dev *pdev)
135562306a36Sopenharmony_ci{
135662306a36Sopenharmony_ci	struct hisi_qm *qm = pci_get_drvdata(pdev);
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	hisi_qm_pm_uninit(qm);
135962306a36Sopenharmony_ci	hisi_qm_wait_task_finish(qm, &zip_devices);
136062306a36Sopenharmony_ci	hisi_qm_alg_unregister(qm, &zip_devices);
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_ci	if (qm->fun_type == QM_HW_PF && qm->vfs_num)
136362306a36Sopenharmony_ci		hisi_qm_sriov_disable(pdev, true);
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	hisi_zip_debugfs_exit(qm);
136662306a36Sopenharmony_ci	hisi_qm_stop(qm, QM_NORMAL);
136762306a36Sopenharmony_ci	hisi_zip_show_last_regs_uninit(qm);
136862306a36Sopenharmony_ci	hisi_qm_dev_err_uninit(qm);
136962306a36Sopenharmony_ci	hisi_zip_qm_uninit(qm);
137062306a36Sopenharmony_ci}
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_cistatic const struct dev_pm_ops hisi_zip_pm_ops = {
137362306a36Sopenharmony_ci	SET_RUNTIME_PM_OPS(hisi_qm_suspend, hisi_qm_resume, NULL)
137462306a36Sopenharmony_ci};
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_cistatic const struct pci_error_handlers hisi_zip_err_handler = {
137762306a36Sopenharmony_ci	.error_detected	= hisi_qm_dev_err_detected,
137862306a36Sopenharmony_ci	.slot_reset	= hisi_qm_dev_slot_reset,
137962306a36Sopenharmony_ci	.reset_prepare	= hisi_qm_reset_prepare,
138062306a36Sopenharmony_ci	.reset_done	= hisi_qm_reset_done,
138162306a36Sopenharmony_ci};
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_cistatic struct pci_driver hisi_zip_pci_driver = {
138462306a36Sopenharmony_ci	.name			= "hisi_zip",
138562306a36Sopenharmony_ci	.id_table		= hisi_zip_dev_ids,
138662306a36Sopenharmony_ci	.probe			= hisi_zip_probe,
138762306a36Sopenharmony_ci	.remove			= hisi_zip_remove,
138862306a36Sopenharmony_ci	.sriov_configure	= IS_ENABLED(CONFIG_PCI_IOV) ?
138962306a36Sopenharmony_ci					hisi_qm_sriov_configure : NULL,
139062306a36Sopenharmony_ci	.err_handler		= &hisi_zip_err_handler,
139162306a36Sopenharmony_ci	.shutdown		= hisi_qm_dev_shutdown,
139262306a36Sopenharmony_ci	.driver.pm		= &hisi_zip_pm_ops,
139362306a36Sopenharmony_ci};
139462306a36Sopenharmony_ci
139562306a36Sopenharmony_cistruct pci_driver *hisi_zip_get_pf_driver(void)
139662306a36Sopenharmony_ci{
139762306a36Sopenharmony_ci	return &hisi_zip_pci_driver;
139862306a36Sopenharmony_ci}
139962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(hisi_zip_get_pf_driver);
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_cistatic void hisi_zip_register_debugfs(void)
140262306a36Sopenharmony_ci{
140362306a36Sopenharmony_ci	if (!debugfs_initialized())
140462306a36Sopenharmony_ci		return;
140562306a36Sopenharmony_ci
140662306a36Sopenharmony_ci	hzip_debugfs_root = debugfs_create_dir("hisi_zip", NULL);
140762306a36Sopenharmony_ci}
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_cistatic void hisi_zip_unregister_debugfs(void)
141062306a36Sopenharmony_ci{
141162306a36Sopenharmony_ci	debugfs_remove_recursive(hzip_debugfs_root);
141262306a36Sopenharmony_ci}
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_cistatic int __init hisi_zip_init(void)
141562306a36Sopenharmony_ci{
141662306a36Sopenharmony_ci	int ret;
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_ci	hisi_qm_init_list(&zip_devices);
141962306a36Sopenharmony_ci	hisi_zip_register_debugfs();
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	ret = pci_register_driver(&hisi_zip_pci_driver);
142262306a36Sopenharmony_ci	if (ret < 0) {
142362306a36Sopenharmony_ci		hisi_zip_unregister_debugfs();
142462306a36Sopenharmony_ci		pr_err("Failed to register pci driver.\n");
142562306a36Sopenharmony_ci	}
142662306a36Sopenharmony_ci
142762306a36Sopenharmony_ci	return ret;
142862306a36Sopenharmony_ci}
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_cistatic void __exit hisi_zip_exit(void)
143162306a36Sopenharmony_ci{
143262306a36Sopenharmony_ci	pci_unregister_driver(&hisi_zip_pci_driver);
143362306a36Sopenharmony_ci	hisi_zip_unregister_debugfs();
143462306a36Sopenharmony_ci}
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_cimodule_init(hisi_zip_init);
143762306a36Sopenharmony_cimodule_exit(hisi_zip_exit);
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
144062306a36Sopenharmony_ciMODULE_AUTHOR("Zhou Wang <wangzhou1@hisilicon.com>");
144162306a36Sopenharmony_ciMODULE_DESCRIPTION("Driver for HiSilicon ZIP accelerator");
1442