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