Path: blob/master/drivers/crypto/hisilicon/zip/zip_main.c
29524 views
// SPDX-License-Identifier: GPL-2.01/* Copyright (c) 2019 HiSilicon Limited. */2#include <linux/acpi.h>3#include <linux/bitops.h>4#include <linux/debugfs.h>5#include <linux/init.h>6#include <linux/io.h>7#include <linux/kernel.h>8#include <linux/module.h>9#include <linux/pci.h>10#include <linux/pm_runtime.h>11#include <linux/seq_file.h>12#include <linux/topology.h>13#include <linux/uacce.h>14#include "zip.h"1516#define CAP_FILE_PERMISSION 044417#define PCI_DEVICE_ID_HUAWEI_ZIP_PF 0xa2501819#define HZIP_QUEUE_NUM_V1 40962021#define HZIP_CLOCK_GATE_CTRL 0x30100422#define HZIP_DECOMP_CHECK_ENABLE BIT(16)23#define HZIP_FSM_MAX_CNT 0x3010082425#define HZIP_PORT_ARCA_CHE_0 0x30104026#define HZIP_PORT_ARCA_CHE_1 0x30104427#define HZIP_PORT_AWCA_CHE_0 0x30106028#define HZIP_PORT_AWCA_CHE_1 0x30106429#define HZIP_CACHE_ALL_EN 0xffffffff3031#define HZIP_BD_RUSER_32_63 0x30111032#define HZIP_SGL_RUSER_32_63 0x30111c33#define HZIP_DATA_RUSER_32_63 0x30112834#define HZIP_DATA_WUSER_32_63 0x30113435#define HZIP_BD_WUSER_32_63 0x3011403637#define HZIP_QM_IDEL_STATUS 0x3040e43839#define HZIP_CORE_DFX_BASE 0x30100040#define HZIP_CORE_DFX_DECOMP_BASE 0x30400041#define HZIP_CORE_DFX_COMP_0 0x30200042#define HZIP_CORE_DFX_COMP_1 0x30300043#define HZIP_CORE_DFX_DECOMP_0 0x30400044#define HZIP_CORE_DFX_DECOMP_1 0x30500045#define HZIP_CORE_DFX_DECOMP_2 0x30600046#define HZIP_CORE_DFX_DECOMP_3 0x30700047#define HZIP_CORE_DFX_DECOMP_4 0x30800048#define HZIP_CORE_DFX_DECOMP_5 0x30900049#define HZIP_CORE_REGS_BASE_LEN 0xB050#define HZIP_CORE_REGS_DFX_LEN 0x2851#define HZIP_CORE_ADDR_INTRVL 0x10005253#define HZIP_CORE_INT_SOURCE 0x3010A054#define HZIP_CORE_INT_MASK_REG 0x3010A455#define HZIP_CORE_INT_SET 0x3010A856#define HZIP_CORE_INT_STATUS 0x3010AC57#define HZIP_CORE_INT_STATUS_M_ECC BIT(1)58#define HZIP_CORE_SRAM_ECC_ERR_INFO 0x30114859#define HZIP_CORE_INT_RAS_CE_ENB 0x30116060#define HZIP_CORE_INT_RAS_NFE_ENB 0x30116461#define HZIP_CORE_INT_RAS_FE_ENB 0x30116862#define HZIP_CORE_INT_RAS_FE_ENB_MASK 0x063#define HZIP_OOO_SHUTDOWN_SEL 0x30120C64#define HZIP_SRAM_ECC_ERR_NUM_SHIFT 1665#define HZIP_SRAM_ECC_ERR_ADDR_SHIFT 2466#define HZIP_CORE_INT_MASK_ALL GENMASK(12, 0)67#define HZIP_AXI_ERROR_MASK (BIT(2) | BIT(3))68#define HZIP_SQE_SIZE 12869#define HZIP_PF_DEF_Q_NUM 6470#define HZIP_PF_DEF_Q_BASE 071#define HZIP_CTX_Q_NUM_DEF 27273#define HZIP_SOFT_CTRL_CNT_CLR_CE 0x30100074#define HZIP_SOFT_CTRL_CNT_CLR_CE_BIT BIT(0)75#define HZIP_SOFT_CTRL_ZIP_CONTROL 0x30100C76#define HZIP_AXI_SHUTDOWN_ENABLE BIT(14)77#define HZIP_WR_PORT BIT(11)7879#define HZIP_ALG_ZLIB_BIT GENMASK(1, 0)80#define HZIP_ALG_GZIP_BIT GENMASK(3, 2)81#define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4)82#define HZIP_ALG_LZ77_BIT GENMASK(7, 6)83#define HZIP_ALG_LZ4_BIT GENMASK(9, 8)8485#define HZIP_BUF_SIZE 2286#define HZIP_SQE_MASK_OFFSET 6487#define HZIP_SQE_MASK_LEN 488889#define HZIP_CNT_CLR_CE_EN BIT(0)90#define HZIP_RO_CNT_CLR_CE_EN BIT(2)91#define HZIP_RD_CNT_CLR_CE_EN (HZIP_CNT_CLR_CE_EN | \92HZIP_RO_CNT_CLR_CE_EN)9394#define HZIP_PREFETCH_CFG 0x3011B095#define HZIP_SVA_TRANS 0x3011C496#define HZIP_PREFETCH_ENABLE (~(BIT(26) | BIT(17) | BIT(0)))97#define HZIP_SVA_PREFETCH_DISABLE BIT(26)98#define HZIP_SVA_DISABLE_READY (BIT(26) | BIT(30))99#define HZIP_SVA_PREFETCH_NUM GENMASK(18, 16)100#define HZIP_SVA_STALL_NUM GENMASK(15, 0)101#define HZIP_SHAPER_RATE_COMPRESS 750102#define HZIP_SHAPER_RATE_DECOMPRESS 140103#define HZIP_DELAY_1_US 1104#define HZIP_POLL_TIMEOUT_US 1000105#define HZIP_WAIT_SVA_READY 500000106#define HZIP_READ_SVA_STATUS_TIMES 3107#define HZIP_WAIT_US_MIN 10108#define HZIP_WAIT_US_MAX 20109110/* clock gating */111#define HZIP_PEH_CFG_AUTO_GATE 0x3011A8112#define HZIP_PEH_CFG_AUTO_GATE_EN BIT(0)113#define HZIP_CORE_GATED_EN GENMASK(15, 8)114#define HZIP_CORE_GATED_OOO_EN BIT(29)115#define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \116HZIP_CORE_GATED_OOO_EN)117118/* zip comp high performance */119#define HZIP_HIGH_PERF_OFFSET 0x301208120121#define HZIP_LIT_LEN_EN_OFFSET 0x301204122#define HZIP_LIT_LEN_EN_EN BIT(4)123124enum {125HZIP_HIGH_COMP_RATE,126HZIP_HIGH_COMP_PERF,127};128129static const char hisi_zip_name[] = "hisi_zip";130static struct dentry *hzip_debugfs_root;131132struct hisi_zip_hw_error {133u32 int_msk;134const char *msg;135};136137struct zip_dfx_item {138const char *name;139u32 offset;140};141142static const struct qm_dev_alg zip_dev_algs[] = { {143.alg_msk = HZIP_ALG_ZLIB_BIT,144.alg = "zlib\n",145}, {146.alg_msk = HZIP_ALG_GZIP_BIT,147.alg = "gzip\n",148}, {149.alg_msk = HZIP_ALG_DEFLATE_BIT,150.alg = "deflate\n",151}, {152.alg_msk = HZIP_ALG_LZ77_BIT,153.alg = "lz77_zstd\n",154}, {155.alg_msk = HZIP_ALG_LZ77_BIT,156.alg = "lz77_only\n",157}, {158.alg_msk = HZIP_ALG_LZ4_BIT,159.alg = "lz4\n",160},161};162163static struct hisi_qm_list zip_devices = {164.register_to_crypto = hisi_zip_register_to_crypto,165.unregister_from_crypto = hisi_zip_unregister_from_crypto,166};167168static struct zip_dfx_item zip_dfx_files[] = {169{"send_cnt", offsetof(struct hisi_zip_dfx, send_cnt)},170{"recv_cnt", offsetof(struct hisi_zip_dfx, recv_cnt)},171{"send_busy_cnt", offsetof(struct hisi_zip_dfx, send_busy_cnt)},172{"err_bd_cnt", offsetof(struct hisi_zip_dfx, err_bd_cnt)},173};174175static const struct hisi_zip_hw_error zip_hw_error[] = {176{ .int_msk = BIT(0), .msg = "zip_ecc_1bitt_err" },177{ .int_msk = BIT(1), .msg = "zip_ecc_2bit_err" },178{ .int_msk = BIT(2), .msg = "zip_axi_rresp_err" },179{ .int_msk = BIT(3), .msg = "zip_axi_bresp_err" },180{ .int_msk = BIT(4), .msg = "zip_src_addr_parse_err" },181{ .int_msk = BIT(5), .msg = "zip_dst_addr_parse_err" },182{ .int_msk = BIT(6), .msg = "zip_pre_in_addr_err" },183{ .int_msk = BIT(7), .msg = "zip_pre_in_data_err" },184{ .int_msk = BIT(8), .msg = "zip_com_inf_err" },185{ .int_msk = BIT(9), .msg = "zip_enc_inf_err" },186{ .int_msk = BIT(10), .msg = "zip_pre_out_err" },187{ .int_msk = BIT(11), .msg = "zip_axi_poison_err" },188{ .int_msk = BIT(12), .msg = "zip_sva_err" },189{ /* sentinel */ }190};191192enum ctrl_debug_file_index {193HZIP_CLEAR_ENABLE,194HZIP_DEBUG_FILE_NUM,195};196197static const char * const ctrl_debug_file_name[] = {198[HZIP_CLEAR_ENABLE] = "clear_enable",199};200201struct ctrl_debug_file {202enum ctrl_debug_file_index index;203spinlock_t lock;204struct hisi_zip_ctrl *ctrl;205};206207/*208* One ZIP controller has one PF and multiple VFs, some global configurations209* which PF has need this structure.210*211* Just relevant for PF.212*/213struct hisi_zip_ctrl {214struct hisi_zip *hisi_zip;215struct ctrl_debug_file files[HZIP_DEBUG_FILE_NUM];216};217218enum zip_cap_type {219ZIP_QM_NFE_MASK_CAP = 0x0,220ZIP_QM_RESET_MASK_CAP,221ZIP_QM_OOO_SHUTDOWN_MASK_CAP,222ZIP_QM_CE_MASK_CAP,223ZIP_NFE_MASK_CAP,224ZIP_RESET_MASK_CAP,225ZIP_OOO_SHUTDOWN_MASK_CAP,226ZIP_CE_MASK_CAP,227ZIP_CLUSTER_NUM_CAP,228ZIP_CORE_TYPE_NUM_CAP,229ZIP_CORE_NUM_CAP,230ZIP_CLUSTER_COMP_NUM_CAP,231ZIP_CLUSTER_DECOMP_NUM_CAP,232ZIP_DECOMP_ENABLE_BITMAP,233ZIP_COMP_ENABLE_BITMAP,234ZIP_DRV_ALG_BITMAP,235ZIP_DEV_ALG_BITMAP,236ZIP_CORE1_ALG_BITMAP,237ZIP_CORE2_ALG_BITMAP,238ZIP_CORE3_ALG_BITMAP,239ZIP_CORE4_ALG_BITMAP,240ZIP_CORE5_ALG_BITMAP,241ZIP_CAP_MAX242};243244static struct hisi_qm_cap_info zip_basic_cap_info[] = {245{ZIP_QM_NFE_MASK_CAP, 0x3124, 0, GENMASK(31, 0), 0x0, 0x1C57, 0x7C77},246{ZIP_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC57, 0x6C77},247{ZIP_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C77},248{ZIP_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8},249{ZIP_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x7FE, 0x1FFE},250{ZIP_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x7FE, 0x7FE},251{ZIP_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x2, 0x7FE},252{ZIP_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x1, 0x1},253{ZIP_CLUSTER_NUM_CAP, 0x313C, 28, GENMASK(3, 0), 0x1, 0x1, 0x1},254{ZIP_CORE_TYPE_NUM_CAP, 0x313C, 24, GENMASK(3, 0), 0x2, 0x2, 0x2},255{ZIP_CORE_NUM_CAP, 0x313C, 16, GENMASK(7, 0), 0x8, 0x8, 0x5},256{ZIP_CLUSTER_COMP_NUM_CAP, 0x313C, 8, GENMASK(7, 0), 0x2, 0x2, 0x2},257{ZIP_CLUSTER_DECOMP_NUM_CAP, 0x313C, 0, GENMASK(7, 0), 0x6, 0x6, 0x3},258{ZIP_DECOMP_ENABLE_BITMAP, 0x3140, 16, GENMASK(15, 0), 0xFC, 0xFC, 0x1C},259{ZIP_COMP_ENABLE_BITMAP, 0x3140, 0, GENMASK(15, 0), 0x3, 0x3, 0x3},260{ZIP_DRV_ALG_BITMAP, 0x3144, 0, GENMASK(31, 0), 0x0, 0x0, 0x30},261{ZIP_DEV_ALG_BITMAP, 0x3148, 0, GENMASK(31, 0), 0xF, 0xF, 0x3F},262{ZIP_CORE1_ALG_BITMAP, 0x314C, 0, GENMASK(31, 0), 0x5, 0x5, 0xD5},263{ZIP_CORE2_ALG_BITMAP, 0x3150, 0, GENMASK(31, 0), 0x5, 0x5, 0xD5},264{ZIP_CORE3_ALG_BITMAP, 0x3154, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},265{ZIP_CORE4_ALG_BITMAP, 0x3158, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},266{ZIP_CORE5_ALG_BITMAP, 0x315C, 0, GENMASK(31, 0), 0xA, 0xA, 0x2A},267{ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0}268};269270static const struct hisi_qm_cap_query_info zip_cap_query_info[] = {271{QM_RAS_NFE_TYPE, "QM_RAS_NFE_TYPE ", 0x3124, 0x0, 0x1C57, 0x7C77},272{QM_RAS_NFE_RESET, "QM_RAS_NFE_RESET ", 0x3128, 0x0, 0xC57, 0x6C77},273{QM_RAS_CE_TYPE, "QM_RAS_CE_TYPE ", 0x312C, 0x0, 0x8, 0x8},274{ZIP_RAS_NFE_TYPE, "ZIP_RAS_NFE_TYPE ", 0x3130, 0x0, 0x7FE, 0x1FFE},275{ZIP_RAS_NFE_RESET, "ZIP_RAS_NFE_RESET ", 0x3134, 0x0, 0x7FE, 0x7FE},276{ZIP_RAS_CE_TYPE, "ZIP_RAS_CE_TYPE ", 0x3138, 0x0, 0x1, 0x1},277{ZIP_CORE_INFO, "ZIP_CORE_INFO ", 0x313C, 0x12080206, 0x12080206, 0x12050203},278{ZIP_CORE_EN, "ZIP_CORE_EN ", 0x3140, 0xFC0003, 0xFC0003, 0x1C0003},279{ZIP_DRV_ALG_BITMAP_TB, "ZIP_DRV_ALG_BITMAP ", 0x3144, 0x0, 0x0, 0x30},280{ZIP_ALG_BITMAP, "ZIP_ALG_BITMAP ", 0x3148, 0xF, 0xF, 0x3F},281{ZIP_CORE1_BITMAP, "ZIP_CORE1_BITMAP ", 0x314C, 0x5, 0x5, 0xD5},282{ZIP_CORE2_BITMAP, "ZIP_CORE2_BITMAP ", 0x3150, 0x5, 0x5, 0xD5},283{ZIP_CORE3_BITMAP, "ZIP_CORE3_BITMAP ", 0x3154, 0xA, 0xA, 0x2A},284{ZIP_CORE4_BITMAP, "ZIP_CORE4_BITMAP ", 0x3158, 0xA, 0xA, 0x2A},285{ZIP_CORE5_BITMAP, "ZIP_CORE5_BITMAP ", 0x315C, 0xA, 0xA, 0x2A},286};287288static const struct debugfs_reg32 hzip_dfx_regs[] = {289{"HZIP_GET_BD_NUM ", 0x00},290{"HZIP_GET_RIGHT_BD ", 0x04},291{"HZIP_GET_ERROR_BD ", 0x08},292{"HZIP_DONE_BD_NUM ", 0x0c},293{"HZIP_WORK_CYCLE ", 0x10},294{"HZIP_IDLE_CYCLE ", 0x18},295{"HZIP_MAX_DELAY ", 0x20},296{"HZIP_MIN_DELAY ", 0x24},297{"HZIP_AVG_DELAY ", 0x28},298{"HZIP_MEM_VISIBLE_DATA ", 0x30},299{"HZIP_MEM_VISIBLE_ADDR ", 0x34},300{"HZIP_CONSUMED_BYTE ", 0x38},301{"HZIP_PRODUCED_BYTE ", 0x40},302{"HZIP_COMP_INF ", 0x70},303{"HZIP_PRE_OUT ", 0x78},304{"HZIP_BD_RD ", 0x7c},305{"HZIP_BD_WR ", 0x80},306{"HZIP_GET_BD_AXI_ERR_NUM ", 0x84},307{"HZIP_GET_BD_PARSE_ERR_NUM ", 0x88},308{"HZIP_ADD_BD_AXI_ERR_NUM ", 0x8c},309{"HZIP_DECOMP_STF_RELOAD_CURR_ST ", 0x94},310{"HZIP_DECOMP_LZ77_CURR_ST ", 0x9c},311};312313static const struct debugfs_reg32 hzip_com_dfx_regs[] = {314{"HZIP_CLOCK_GATE_CTRL ", 0x301004},315{"HZIP_CORE_INT_RAS_CE_ENB ", 0x301160},316{"HZIP_CORE_INT_RAS_NFE_ENB ", 0x301164},317{"HZIP_CORE_INT_RAS_FE_ENB ", 0x301168},318{"HZIP_UNCOM_ERR_RAS_CTRL ", 0x30116C},319};320321static const struct debugfs_reg32 hzip_dump_dfx_regs[] = {322{"HZIP_GET_BD_NUM ", 0x00},323{"HZIP_GET_RIGHT_BD ", 0x04},324{"HZIP_GET_ERROR_BD ", 0x08},325{"HZIP_DONE_BD_NUM ", 0x0c},326{"HZIP_MAX_DELAY ", 0x20},327};328329/* define the ZIP's dfx regs region and region length */330static struct dfx_diff_registers hzip_diff_regs[] = {331{332.reg_offset = HZIP_CORE_DFX_BASE,333.reg_len = HZIP_CORE_REGS_BASE_LEN,334}, {335.reg_offset = HZIP_CORE_DFX_COMP_0,336.reg_len = HZIP_CORE_REGS_DFX_LEN,337}, {338.reg_offset = HZIP_CORE_DFX_COMP_1,339.reg_len = HZIP_CORE_REGS_DFX_LEN,340}, {341.reg_offset = HZIP_CORE_DFX_DECOMP_0,342.reg_len = HZIP_CORE_REGS_DFX_LEN,343}, {344.reg_offset = HZIP_CORE_DFX_DECOMP_1,345.reg_len = HZIP_CORE_REGS_DFX_LEN,346}, {347.reg_offset = HZIP_CORE_DFX_DECOMP_2,348.reg_len = HZIP_CORE_REGS_DFX_LEN,349}, {350.reg_offset = HZIP_CORE_DFX_DECOMP_3,351.reg_len = HZIP_CORE_REGS_DFX_LEN,352}, {353.reg_offset = HZIP_CORE_DFX_DECOMP_4,354.reg_len = HZIP_CORE_REGS_DFX_LEN,355}, {356.reg_offset = HZIP_CORE_DFX_DECOMP_5,357.reg_len = HZIP_CORE_REGS_DFX_LEN,358},359};360361static int hzip_diff_regs_show(struct seq_file *s, void *unused)362{363struct hisi_qm *qm = s->private;364365hisi_qm_acc_diff_regs_dump(qm, s, qm->debug.acc_diff_regs,366ARRAY_SIZE(hzip_diff_regs));367368return 0;369}370DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs);371372static int perf_mode_set(const char *val, const struct kernel_param *kp)373{374int ret;375u32 n;376377if (!val)378return -EINVAL;379380ret = kstrtou32(val, 10, &n);381if (ret != 0 || (n != HZIP_HIGH_COMP_PERF &&382n != HZIP_HIGH_COMP_RATE))383return -EINVAL;384385return param_set_int(val, kp);386}387388static const struct kernel_param_ops zip_com_perf_ops = {389.set = perf_mode_set,390.get = param_get_int,391};392393/*394* perf_mode = 0 means enable high compression rate mode,395* perf_mode = 1 means enable high compression performance mode.396* These two modes only apply to the compression direction.397*/398static u32 perf_mode = HZIP_HIGH_COMP_RATE;399module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444);400MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)");401402static const struct kernel_param_ops zip_uacce_mode_ops = {403.set = uacce_mode_set,404.get = param_get_int,405};406407/*408* uacce_mode = 0 means zip only register to crypto,409* uacce_mode = 1 means zip both register to crypto and uacce.410*/411static u32 uacce_mode = UACCE_MODE_NOUACCE;412module_param_cb(uacce_mode, &zip_uacce_mode_ops, &uacce_mode, 0444);413MODULE_PARM_DESC(uacce_mode, UACCE_MODE_DESC);414415static bool pf_q_num_flag;416static int pf_q_num_set(const char *val, const struct kernel_param *kp)417{418pf_q_num_flag = true;419420return hisi_qm_q_num_set(val, kp, PCI_DEVICE_ID_HUAWEI_ZIP_PF);421}422423static const struct kernel_param_ops pf_q_num_ops = {424.set = pf_q_num_set,425.get = param_get_int,426};427428static u32 pf_q_num = HZIP_PF_DEF_Q_NUM;429module_param_cb(pf_q_num, &pf_q_num_ops, &pf_q_num, 0444);430MODULE_PARM_DESC(pf_q_num, "Number of queues in PF(v1 2-4096, v2 2-1024)");431432static const struct kernel_param_ops vfs_num_ops = {433.set = vfs_num_set,434.get = param_get_int,435};436437static u32 vfs_num;438module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444);439MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)");440441static const struct pci_device_id hisi_zip_dev_ids[] = {442{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_PF) },443{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HUAWEI_ZIP_VF) },444{ 0, }445};446MODULE_DEVICE_TABLE(pci, hisi_zip_dev_ids);447448int zip_create_qps(struct hisi_qp **qps, int qp_num, int node)449{450if (node == NUMA_NO_NODE)451node = cpu_to_node(raw_smp_processor_id());452453return hisi_qm_alloc_qps_node(&zip_devices, qp_num, 0, node, qps);454}455456bool hisi_zip_alg_support(struct hisi_qm *qm, u32 alg)457{458u32 cap_val;459460cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_TB].cap_val;461if ((alg & cap_val) == alg)462return true;463464return false;465}466467static void hisi_zip_literal_set(struct hisi_qm *qm)468{469u32 val;470471if (qm->ver < QM_HW_V3)472return;473474val = readl_relaxed(qm->io_base + HZIP_LIT_LEN_EN_OFFSET);475val &= ~HZIP_LIT_LEN_EN_EN;476477/* enable literal length in stream mode compression */478writel(val, qm->io_base + HZIP_LIT_LEN_EN_OFFSET);479}480481static void hisi_zip_set_high_perf(struct hisi_qm *qm)482{483u32 val;484485val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET);486if (perf_mode == HZIP_HIGH_COMP_PERF)487val |= HZIP_HIGH_COMP_PERF;488else489val &= ~HZIP_HIGH_COMP_PERF;490491/* Set perf mode */492writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET);493}494495static int hisi_zip_wait_sva_ready(struct hisi_qm *qm, __u32 offset, __u32 mask)496{497u32 val, try_times = 0;498u8 count = 0;499500/*501* Read the register value every 10-20us. If the value is 0 for three502* consecutive times, the SVA module is ready.503*/504do {505val = readl(qm->io_base + offset);506if (val & mask)507count = 0;508else if (++count == HZIP_READ_SVA_STATUS_TIMES)509break;510511usleep_range(HZIP_WAIT_US_MIN, HZIP_WAIT_US_MAX);512} while (++try_times < HZIP_WAIT_SVA_READY);513514if (try_times == HZIP_WAIT_SVA_READY) {515pci_err(qm->pdev, "failed to wait sva prefetch ready\n");516return -ETIMEDOUT;517}518519return 0;520}521522static void hisi_zip_close_sva_prefetch(struct hisi_qm *qm)523{524u32 val;525int ret;526527if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))528return;529530val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);531val |= HZIP_SVA_PREFETCH_DISABLE;532writel(val, qm->io_base + HZIP_PREFETCH_CFG);533534ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_SVA_TRANS,535val, !(val & HZIP_SVA_DISABLE_READY),536HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);537if (ret)538pci_err(qm->pdev, "failed to close sva prefetch\n");539540(void)hisi_zip_wait_sva_ready(qm, HZIP_SVA_TRANS, HZIP_SVA_STALL_NUM);541}542543static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm)544{545u32 val;546int ret;547548if (!test_bit(QM_SUPPORT_SVA_PREFETCH, &qm->caps))549return;550551/* Enable prefetch */552val = readl_relaxed(qm->io_base + HZIP_PREFETCH_CFG);553val &= HZIP_PREFETCH_ENABLE;554writel(val, qm->io_base + HZIP_PREFETCH_CFG);555556ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_PREFETCH_CFG,557val, !(val & HZIP_SVA_PREFETCH_DISABLE),558HZIP_DELAY_1_US, HZIP_POLL_TIMEOUT_US);559if (ret) {560pci_err(qm->pdev, "failed to open sva prefetch\n");561hisi_zip_close_sva_prefetch(qm);562return;563}564565ret = hisi_zip_wait_sva_ready(qm, HZIP_SVA_TRANS, HZIP_SVA_PREFETCH_NUM);566if (ret)567hisi_zip_close_sva_prefetch(qm);568}569570static void hisi_zip_enable_clock_gate(struct hisi_qm *qm)571{572u32 val;573574if (qm->ver < QM_HW_V3)575return;576577val = readl(qm->io_base + HZIP_CLOCK_GATE_CTRL);578val |= HZIP_CLOCK_GATED_EN;579writel(val, qm->io_base + HZIP_CLOCK_GATE_CTRL);580581val = readl(qm->io_base + HZIP_PEH_CFG_AUTO_GATE);582val |= HZIP_PEH_CFG_AUTO_GATE_EN;583writel(val, qm->io_base + HZIP_PEH_CFG_AUTO_GATE);584}585586static int hisi_zip_set_user_domain_and_cache(struct hisi_qm *qm)587{588void __iomem *base = qm->io_base;589u32 dcomp_bm, comp_bm;590u32 zip_core_en;591int ret;592593/* qm user domain */594writel(AXUSER_BASE, base + QM_ARUSER_M_CFG_1);595writel(ARUSER_M_CFG_ENABLE, base + QM_ARUSER_M_CFG_ENABLE);596writel(AXUSER_BASE, base + QM_AWUSER_M_CFG_1);597writel(AWUSER_M_CFG_ENABLE, base + QM_AWUSER_M_CFG_ENABLE);598writel(WUSER_M_CFG_ENABLE, base + QM_WUSER_M_CFG_ENABLE);599600/* qm cache */601writel(AXI_M_CFG, base + QM_AXI_M_CFG);602writel(AXI_M_CFG_ENABLE, base + QM_AXI_M_CFG_ENABLE);603604/* disable FLR triggered by BME(bus master enable) */605writel(PEH_AXUSER_CFG, base + QM_PEH_AXUSER_CFG);606writel(PEH_AXUSER_CFG_ENABLE, base + QM_PEH_AXUSER_CFG_ENABLE);607608/* cache */609writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_ARCA_CHE_0);610writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_ARCA_CHE_1);611writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_AWCA_CHE_0);612writel(HZIP_CACHE_ALL_EN, base + HZIP_PORT_AWCA_CHE_1);613614/* user domain configurations */615writel(AXUSER_BASE, base + HZIP_BD_RUSER_32_63);616writel(AXUSER_BASE, base + HZIP_BD_WUSER_32_63);617618if (qm->use_sva && qm->ver == QM_HW_V2) {619writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_RUSER_32_63);620writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_DATA_WUSER_32_63);621writel(AXUSER_BASE | AXUSER_SSV, base + HZIP_SGL_RUSER_32_63);622} else {623writel(AXUSER_BASE, base + HZIP_DATA_RUSER_32_63);624writel(AXUSER_BASE, base + HZIP_DATA_WUSER_32_63);625writel(AXUSER_BASE, base + HZIP_SGL_RUSER_32_63);626}627hisi_zip_open_sva_prefetch(qm);628629/* let's open all compression/decompression cores */630631zip_core_en = qm->cap_tables.dev_cap_table[ZIP_CORE_EN].cap_val;632dcomp_bm = (zip_core_en >> zip_basic_cap_info[ZIP_DECOMP_ENABLE_BITMAP].shift) &633zip_basic_cap_info[ZIP_DECOMP_ENABLE_BITMAP].mask;634comp_bm = (zip_core_en >> zip_basic_cap_info[ZIP_COMP_ENABLE_BITMAP].shift) &635zip_basic_cap_info[ZIP_COMP_ENABLE_BITMAP].mask;636writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL);637638/* enable sqc,cqc writeback */639writel(SQC_CACHE_ENABLE | CQC_CACHE_ENABLE | SQC_CACHE_WB_ENABLE |640CQC_CACHE_WB_ENABLE | FIELD_PREP(SQC_CACHE_WB_THRD, 1) |641FIELD_PREP(CQC_CACHE_WB_THRD, 1), base + QM_CACHE_CTL);642643hisi_zip_set_high_perf(qm);644hisi_zip_literal_set(qm);645hisi_zip_enable_clock_gate(qm);646647ret = hisi_dae_set_user_domain(qm);648if (ret)649goto close_sva_prefetch;650651return 0;652653close_sva_prefetch:654hisi_zip_close_sva_prefetch(qm);655return ret;656}657658static void hisi_zip_master_ooo_ctrl(struct hisi_qm *qm, bool enable)659{660u32 val1, val2;661662val1 = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);663if (enable) {664val1 |= HZIP_AXI_SHUTDOWN_ENABLE;665val2 = qm->err_info.dev_err.shutdown_mask;666} else {667val1 &= ~HZIP_AXI_SHUTDOWN_ENABLE;668val2 = 0x0;669}670671if (qm->ver > QM_HW_V2)672writel(val2, qm->io_base + HZIP_OOO_SHUTDOWN_SEL);673674writel(val1, qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);675}676677static void hisi_zip_hw_error_enable(struct hisi_qm *qm)678{679struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;680u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;681682if (qm->ver == QM_HW_V1) {683writel(HZIP_CORE_INT_MASK_ALL,684qm->io_base + HZIP_CORE_INT_MASK_REG);685dev_info(&qm->pdev->dev, "Does not support hw error handle\n");686return;687}688689/* clear ZIP hw error source if having */690writel(err_mask, qm->io_base + HZIP_CORE_INT_SOURCE);691692/* configure error type */693writel(dev_err->ce, qm->io_base + HZIP_CORE_INT_RAS_CE_ENB);694writel(dev_err->fe, qm->io_base + HZIP_CORE_INT_RAS_FE_ENB);695writel(dev_err->nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);696697hisi_zip_master_ooo_ctrl(qm, true);698699/* enable ZIP hw error interrupts */700writel(~err_mask, qm->io_base + HZIP_CORE_INT_MASK_REG);701702hisi_dae_hw_error_enable(qm);703}704705static void hisi_zip_hw_error_disable(struct hisi_qm *qm)706{707struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;708u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;709710/* disable ZIP hw error interrupts */711writel(err_mask, qm->io_base + HZIP_CORE_INT_MASK_REG);712713hisi_zip_master_ooo_ctrl(qm, false);714715hisi_dae_hw_error_disable(qm);716}717718static inline struct hisi_qm *file_to_qm(struct ctrl_debug_file *file)719{720struct hisi_zip *hisi_zip = file->ctrl->hisi_zip;721722return &hisi_zip->qm;723}724725static u32 clear_enable_read(struct hisi_qm *qm)726{727return readl(qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE) &728HZIP_SOFT_CTRL_CNT_CLR_CE_BIT;729}730731static int clear_enable_write(struct hisi_qm *qm, u32 val)732{733u32 tmp;734735if (val != 1 && val != 0)736return -EINVAL;737738tmp = (readl(qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE) &739~HZIP_SOFT_CTRL_CNT_CLR_CE_BIT) | val;740writel(tmp, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);741742return 0;743}744745static ssize_t hisi_zip_ctrl_debug_read(struct file *filp, char __user *buf,746size_t count, loff_t *pos)747{748struct ctrl_debug_file *file = filp->private_data;749struct hisi_qm *qm = file_to_qm(file);750char tbuf[HZIP_BUF_SIZE];751u32 val;752int ret;753754ret = hisi_qm_get_dfx_access(qm);755if (ret)756return ret;757758spin_lock_irq(&file->lock);759switch (file->index) {760case HZIP_CLEAR_ENABLE:761val = clear_enable_read(qm);762break;763default:764goto err_input;765}766spin_unlock_irq(&file->lock);767768hisi_qm_put_dfx_access(qm);769ret = scnprintf(tbuf, sizeof(tbuf), "%u\n", val);770return simple_read_from_buffer(buf, count, pos, tbuf, ret);771772err_input:773spin_unlock_irq(&file->lock);774hisi_qm_put_dfx_access(qm);775return -EINVAL;776}777778static ssize_t hisi_zip_ctrl_debug_write(struct file *filp,779const char __user *buf,780size_t count, loff_t *pos)781{782struct ctrl_debug_file *file = filp->private_data;783struct hisi_qm *qm = file_to_qm(file);784char tbuf[HZIP_BUF_SIZE];785unsigned long val;786int len, ret;787788if (*pos != 0)789return 0;790791if (count >= HZIP_BUF_SIZE)792return -ENOSPC;793794len = simple_write_to_buffer(tbuf, HZIP_BUF_SIZE - 1, pos, buf, count);795if (len < 0)796return len;797798tbuf[len] = '\0';799ret = kstrtoul(tbuf, 0, &val);800if (ret)801return ret;802803ret = hisi_qm_get_dfx_access(qm);804if (ret)805return ret;806807spin_lock_irq(&file->lock);808switch (file->index) {809case HZIP_CLEAR_ENABLE:810ret = clear_enable_write(qm, val);811if (ret)812goto err_input;813break;814default:815ret = -EINVAL;816goto err_input;817}818819ret = count;820821err_input:822spin_unlock_irq(&file->lock);823hisi_qm_put_dfx_access(qm);824return ret;825}826827static const struct file_operations ctrl_debug_fops = {828.owner = THIS_MODULE,829.open = simple_open,830.read = hisi_zip_ctrl_debug_read,831.write = hisi_zip_ctrl_debug_write,832};833834static int zip_debugfs_atomic64_set(void *data, u64 val)835{836if (val)837return -EINVAL;838839atomic64_set((atomic64_t *)data, 0);840841return 0;842}843844static int zip_debugfs_atomic64_get(void *data, u64 *val)845{846*val = atomic64_read((atomic64_t *)data);847848return 0;849}850851DEFINE_DEBUGFS_ATTRIBUTE(zip_atomic64_ops, zip_debugfs_atomic64_get,852zip_debugfs_atomic64_set, "%llu\n");853854static int hisi_zip_regs_show(struct seq_file *s, void *unused)855{856hisi_qm_regs_dump(s, s->private);857858return 0;859}860861DEFINE_SHOW_ATTRIBUTE(hisi_zip_regs);862863static void __iomem *get_zip_core_addr(struct hisi_qm *qm, int core_num)864{865u8 zip_comp_core_num;866u32 zip_core_info;867868zip_core_info = qm->cap_tables.dev_cap_table[ZIP_CORE_INFO].cap_val;869zip_comp_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].shift) &870zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].mask;871872if (core_num < zip_comp_core_num)873return qm->io_base + HZIP_CORE_DFX_BASE +874(core_num + 1) * HZIP_CORE_ADDR_INTRVL;875876return qm->io_base + HZIP_CORE_DFX_DECOMP_BASE +877(core_num - zip_comp_core_num) * HZIP_CORE_ADDR_INTRVL;878}879880static int hisi_zip_core_debug_init(struct hisi_qm *qm)881{882u32 zip_core_num, zip_comp_core_num;883struct device *dev = &qm->pdev->dev;884struct debugfs_regset32 *regset;885u32 zip_core_info;886struct dentry *tmp_d;887char buf[HZIP_BUF_SIZE];888int i;889890zip_core_info = qm->cap_tables.dev_cap_table[ZIP_CORE_INFO].cap_val;891zip_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CORE_NUM_CAP].shift) &892zip_basic_cap_info[ZIP_CORE_NUM_CAP].mask;893zip_comp_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].shift) &894zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].mask;895896for (i = 0; i < zip_core_num; i++) {897if (i < zip_comp_core_num)898scnprintf(buf, sizeof(buf), "comp_core%d", i);899else900scnprintf(buf, sizeof(buf), "decomp_core%d",901i - zip_comp_core_num);902903regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);904if (!regset)905return -ENOENT;906907regset->regs = hzip_dfx_regs;908regset->nregs = ARRAY_SIZE(hzip_dfx_regs);909regset->base = get_zip_core_addr(qm, i);910regset->dev = dev;911912tmp_d = debugfs_create_dir(buf, qm->debug.debug_root);913debugfs_create_file("regs", 0444, tmp_d, regset,914&hisi_zip_regs_fops);915}916917return 0;918}919920static int zip_cap_regs_show(struct seq_file *s, void *unused)921{922struct hisi_qm *qm = s->private;923u32 i, size;924925size = qm->cap_tables.qm_cap_size;926for (i = 0; i < size; i++)927seq_printf(s, "%s= 0x%08x\n", qm->cap_tables.qm_cap_table[i].name,928qm->cap_tables.qm_cap_table[i].cap_val);929930size = qm->cap_tables.dev_cap_size;931for (i = 0; i < size; i++)932seq_printf(s, "%s= 0x%08x\n", qm->cap_tables.dev_cap_table[i].name,933qm->cap_tables.dev_cap_table[i].cap_val);934935return 0;936}937938DEFINE_SHOW_ATTRIBUTE(zip_cap_regs);939940static void hisi_zip_dfx_debug_init(struct hisi_qm *qm)941{942struct dfx_diff_registers *hzip_regs = qm->debug.acc_diff_regs;943struct hisi_zip *zip = container_of(qm, struct hisi_zip, qm);944struct hisi_zip_dfx *dfx = &zip->dfx;945struct dentry *tmp_dir;946void *data;947int i;948949tmp_dir = debugfs_create_dir("zip_dfx", qm->debug.debug_root);950for (i = 0; i < ARRAY_SIZE(zip_dfx_files); i++) {951data = (atomic64_t *)((uintptr_t)dfx + zip_dfx_files[i].offset);952debugfs_create_file(zip_dfx_files[i].name,9530644, tmp_dir, data,954&zip_atomic64_ops);955}956957if (qm->fun_type == QM_HW_PF && hzip_regs)958debugfs_create_file("diff_regs", 0444, tmp_dir,959qm, &hzip_diff_regs_fops);960961debugfs_create_file("cap_regs", CAP_FILE_PERMISSION,962qm->debug.debug_root, qm, &zip_cap_regs_fops);963}964965static int hisi_zip_ctrl_debug_init(struct hisi_qm *qm)966{967struct hisi_zip *zip = container_of(qm, struct hisi_zip, qm);968int i;969970for (i = HZIP_CLEAR_ENABLE; i < HZIP_DEBUG_FILE_NUM; i++) {971spin_lock_init(&zip->ctrl->files[i].lock);972zip->ctrl->files[i].ctrl = zip->ctrl;973zip->ctrl->files[i].index = i;974975debugfs_create_file(ctrl_debug_file_name[i], 0600,976qm->debug.debug_root,977zip->ctrl->files + i,978&ctrl_debug_fops);979}980981return hisi_zip_core_debug_init(qm);982}983984static int hisi_zip_debugfs_init(struct hisi_qm *qm)985{986struct device *dev = &qm->pdev->dev;987int ret;988989ret = hisi_qm_regs_debugfs_init(qm, hzip_diff_regs, ARRAY_SIZE(hzip_diff_regs));990if (ret) {991dev_warn(dev, "Failed to init ZIP diff regs!\n");992return ret;993}994995qm->debug.sqe_mask_offset = HZIP_SQE_MASK_OFFSET;996qm->debug.sqe_mask_len = HZIP_SQE_MASK_LEN;997qm->debug.debug_root = debugfs_create_dir(dev_name(dev),998hzip_debugfs_root);9991000hisi_qm_debug_init(qm);10011002if (qm->fun_type == QM_HW_PF) {1003ret = hisi_zip_ctrl_debug_init(qm);1004if (ret)1005goto debugfs_remove;1006}10071008hisi_zip_dfx_debug_init(qm);10091010return 0;10111012debugfs_remove:1013debugfs_remove_recursive(qm->debug.debug_root);1014hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs));1015return ret;1016}10171018/* hisi_zip_debug_regs_clear() - clear the zip debug regs */1019static void hisi_zip_debug_regs_clear(struct hisi_qm *qm)1020{1021u32 zip_core_info;1022u8 zip_core_num;1023int i, j;10241025zip_core_info = qm->cap_tables.dev_cap_table[ZIP_CORE_INFO].cap_val;1026zip_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CORE_NUM_CAP].shift) &1027zip_basic_cap_info[ZIP_CORE_NUM_CAP].mask;10281029/* enable register read_clear bit */1030writel(HZIP_RD_CNT_CLR_CE_EN, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);1031for (i = 0; i < zip_core_num; i++)1032for (j = 0; j < ARRAY_SIZE(hzip_dfx_regs); j++)1033readl(get_zip_core_addr(qm, i) +1034hzip_dfx_regs[j].offset);10351036/* disable register read_clear bit */1037writel(0x0, qm->io_base + HZIP_SOFT_CTRL_CNT_CLR_CE);10381039hisi_qm_debug_regs_clear(qm);1040}10411042static void hisi_zip_debugfs_exit(struct hisi_qm *qm)1043{1044debugfs_remove_recursive(qm->debug.debug_root);10451046hisi_qm_regs_debugfs_uninit(qm, ARRAY_SIZE(hzip_diff_regs));10471048if (qm->fun_type == QM_HW_PF) {1049hisi_zip_debug_regs_clear(qm);1050qm->debug.curr_qm_qp_num = 0;1051}1052}10531054static int hisi_zip_show_last_regs_init(struct hisi_qm *qm)1055{1056int core_dfx_regs_num = ARRAY_SIZE(hzip_dump_dfx_regs);1057int com_dfx_regs_num = ARRAY_SIZE(hzip_com_dfx_regs);1058struct qm_debug *debug = &qm->debug;1059void __iomem *io_base;1060u32 zip_core_info;1061u32 zip_core_num;1062int i, j, idx;10631064zip_core_info = qm->cap_tables.dev_cap_table[ZIP_CORE_INFO].cap_val;1065zip_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CORE_NUM_CAP].shift) &1066zip_basic_cap_info[ZIP_CORE_NUM_CAP].mask;10671068debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num,1069sizeof(unsigned int), GFP_KERNEL);1070if (!debug->last_words)1071return -ENOMEM;10721073for (i = 0; i < com_dfx_regs_num; i++) {1074io_base = qm->io_base + hzip_com_dfx_regs[i].offset;1075debug->last_words[i] = readl_relaxed(io_base);1076}10771078for (i = 0; i < zip_core_num; i++) {1079io_base = get_zip_core_addr(qm, i);1080for (j = 0; j < core_dfx_regs_num; j++) {1081idx = com_dfx_regs_num + i * core_dfx_regs_num + j;1082debug->last_words[idx] = readl_relaxed(1083io_base + hzip_dump_dfx_regs[j].offset);1084}1085}10861087return 0;1088}10891090static void hisi_zip_show_last_regs_uninit(struct hisi_qm *qm)1091{1092struct qm_debug *debug = &qm->debug;10931094if (qm->fun_type == QM_HW_VF || !debug->last_words)1095return;10961097kfree(debug->last_words);1098debug->last_words = NULL;1099}11001101static void hisi_zip_show_last_dfx_regs(struct hisi_qm *qm)1102{1103int core_dfx_regs_num = ARRAY_SIZE(hzip_dump_dfx_regs);1104int com_dfx_regs_num = ARRAY_SIZE(hzip_com_dfx_regs);1105u32 zip_core_num, zip_comp_core_num;1106struct qm_debug *debug = &qm->debug;1107char buf[HZIP_BUF_SIZE];1108u32 zip_core_info;1109void __iomem *base;1110int i, j, idx;1111u32 val;11121113if (qm->fun_type == QM_HW_VF || !debug->last_words)1114return;11151116for (i = 0; i < com_dfx_regs_num; i++) {1117val = readl_relaxed(qm->io_base + hzip_com_dfx_regs[i].offset);1118if (debug->last_words[i] != val)1119pci_info(qm->pdev, "com_dfx: %s \t= 0x%08x => 0x%08x\n",1120hzip_com_dfx_regs[i].name, debug->last_words[i], val);1121}11221123zip_core_info = qm->cap_tables.dev_cap_table[ZIP_CORE_INFO].cap_val;1124zip_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CORE_NUM_CAP].shift) &1125zip_basic_cap_info[ZIP_CORE_NUM_CAP].mask;1126zip_comp_core_num = (zip_core_info >> zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].shift) &1127zip_basic_cap_info[ZIP_CLUSTER_COMP_NUM_CAP].mask;11281129for (i = 0; i < zip_core_num; i++) {1130if (i < zip_comp_core_num)1131scnprintf(buf, sizeof(buf), "Comp_core-%d", i);1132else1133scnprintf(buf, sizeof(buf), "Decomp_core-%d",1134i - zip_comp_core_num);1135base = get_zip_core_addr(qm, i);11361137pci_info(qm->pdev, "==>%s:\n", buf);1138/* dump last word for dfx regs during control resetting */1139for (j = 0; j < core_dfx_regs_num; j++) {1140idx = com_dfx_regs_num + i * core_dfx_regs_num + j;1141val = readl_relaxed(base + hzip_dump_dfx_regs[j].offset);1142if (debug->last_words[idx] != val)1143pci_info(qm->pdev, "%s \t= 0x%08x => 0x%08x\n",1144hzip_dump_dfx_regs[j].name,1145debug->last_words[idx], val);1146}1147}1148}11491150static void hisi_zip_log_hw_error(struct hisi_qm *qm, u32 err_sts)1151{1152const struct hisi_zip_hw_error *err = zip_hw_error;1153struct device *dev = &qm->pdev->dev;1154u32 err_val;11551156while (err->msg) {1157if (err->int_msk & err_sts) {1158dev_err(dev, "%s [error status=0x%x] found\n",1159err->msg, err->int_msk);11601161if (err->int_msk & HZIP_CORE_INT_STATUS_M_ECC) {1162err_val = readl(qm->io_base +1163HZIP_CORE_SRAM_ECC_ERR_INFO);1164dev_err(dev, "hisi-zip multi ecc sram num=0x%x\n",1165((err_val >>1166HZIP_SRAM_ECC_ERR_NUM_SHIFT) & 0xFF));1167}1168}1169err++;1170}1171}11721173static u32 hisi_zip_get_hw_err_status(struct hisi_qm *qm)1174{1175return readl(qm->io_base + HZIP_CORE_INT_STATUS);1176}11771178static void hisi_zip_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)1179{1180writel(err_sts, qm->io_base + HZIP_CORE_INT_SOURCE);1181}11821183static void hisi_zip_disable_error_report(struct hisi_qm *qm, u32 err_type)1184{1185u32 nfe_mask = qm->err_info.dev_err.nfe;11861187writel(nfe_mask & (~err_type), qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);1188}11891190static void hisi_zip_enable_error_report(struct hisi_qm *qm)1191{1192u32 nfe_mask = qm->err_info.dev_err.nfe;1193u32 ce_mask = qm->err_info.dev_err.ce;11941195writel(nfe_mask, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);1196writel(ce_mask, qm->io_base + HZIP_CORE_INT_RAS_CE_ENB);1197}11981199static void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm)1200{1201u32 val;12021203val = readl(qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);12041205writel(val & ~HZIP_AXI_SHUTDOWN_ENABLE,1206qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);12071208writel(val | HZIP_AXI_SHUTDOWN_ENABLE,1209qm->io_base + HZIP_SOFT_CTRL_ZIP_CONTROL);12101211hisi_dae_open_axi_master_ooo(qm);1212}12131214static void hisi_zip_close_axi_master_ooo(struct hisi_qm *qm)1215{1216u32 nfe_enb;12171218/* Disable ECC Mbit error report. */1219nfe_enb = readl(qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);1220writel(nfe_enb & ~HZIP_CORE_INT_STATUS_M_ECC,1221qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);12221223/* Inject zip ECC Mbit error to block master ooo. */1224writel(HZIP_CORE_INT_STATUS_M_ECC,1225qm->io_base + HZIP_CORE_INT_SET);1226}12271228static enum acc_err_result hisi_zip_get_err_result(struct hisi_qm *qm)1229{1230enum acc_err_result zip_result = ACC_ERR_NONE;1231enum acc_err_result dae_result;1232u32 err_status;12331234/* Get device hardware new error status */1235err_status = hisi_zip_get_hw_err_status(qm);1236if (err_status) {1237if (err_status & qm->err_info.dev_err.ecc_2bits_mask)1238qm->err_status.is_dev_ecc_mbit = true;1239hisi_zip_log_hw_error(qm, err_status);12401241if (err_status & qm->err_info.dev_err.reset_mask) {1242/* Disable the same error reporting until device is recovered. */1243hisi_zip_disable_error_report(qm, err_status);1244zip_result = ACC_ERR_NEED_RESET;1245} else {1246hisi_zip_clear_hw_err_status(qm, err_status);1247/* Avoid firmware disable error report, re-enable. */1248hisi_zip_enable_error_report(qm);1249}1250}12511252dae_result = hisi_dae_get_err_result(qm);12531254return (zip_result == ACC_ERR_NEED_RESET ||1255dae_result == ACC_ERR_NEED_RESET) ?1256ACC_ERR_NEED_RESET : ACC_ERR_RECOVERED;1257}12581259static bool hisi_zip_dev_is_abnormal(struct hisi_qm *qm)1260{1261u32 err_status;12621263err_status = hisi_zip_get_hw_err_status(qm);1264if (err_status & qm->err_info.dev_err.shutdown_mask)1265return true;12661267return hisi_dae_dev_is_abnormal(qm);1268}12691270static int hisi_zip_set_priv_status(struct hisi_qm *qm)1271{1272return hisi_dae_close_axi_master_ooo(qm);1273}12741275static void hisi_zip_disable_axi_error(struct hisi_qm *qm)1276{1277struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;1278u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;1279u32 val;12801281val = ~(err_mask & (~HZIP_AXI_ERROR_MASK));1282writel(val, qm->io_base + HZIP_CORE_INT_MASK_REG);12831284if (qm->ver > QM_HW_V2)1285writel(dev_err->shutdown_mask & (~HZIP_AXI_ERROR_MASK),1286qm->io_base + HZIP_OOO_SHUTDOWN_SEL);1287}12881289static void hisi_zip_enable_axi_error(struct hisi_qm *qm)1290{1291struct hisi_qm_err_mask *dev_err = &qm->err_info.dev_err;1292u32 err_mask = dev_err->ce | dev_err->nfe | dev_err->fe;12931294/* clear axi error source */1295writel(HZIP_AXI_ERROR_MASK, qm->io_base + HZIP_CORE_INT_SOURCE);12961297writel(~err_mask, qm->io_base + HZIP_CORE_INT_MASK_REG);12981299if (qm->ver > QM_HW_V2)1300writel(dev_err->shutdown_mask, qm->io_base + HZIP_OOO_SHUTDOWN_SEL);1301}13021303static void hisi_zip_err_info_init(struct hisi_qm *qm)1304{1305struct hisi_qm_err_info *err_info = &qm->err_info;1306struct hisi_qm_err_mask *qm_err = &err_info->qm_err;1307struct hisi_qm_err_mask *dev_err = &err_info->dev_err;13081309qm_err->fe = HZIP_CORE_INT_RAS_FE_ENB_MASK;1310qm_err->ce = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_QM_CE_MASK_CAP, qm->cap_ver);1311qm_err->nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info,1312ZIP_QM_NFE_MASK_CAP, qm->cap_ver);1313qm_err->ecc_2bits_mask = QM_ECC_MBIT;1314qm_err->reset_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,1315ZIP_QM_RESET_MASK_CAP, qm->cap_ver);1316qm_err->shutdown_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,1317ZIP_QM_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);13181319dev_err->fe = HZIP_CORE_INT_RAS_FE_ENB_MASK;1320dev_err->ce = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CE_MASK_CAP, qm->cap_ver);1321dev_err->nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);1322dev_err->ecc_2bits_mask = HZIP_CORE_INT_STATUS_M_ECC;1323dev_err->shutdown_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,1324ZIP_OOO_SHUTDOWN_MASK_CAP, qm->cap_ver);1325dev_err->reset_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info,1326ZIP_RESET_MASK_CAP, qm->cap_ver);13271328err_info->msi_wr_port = HZIP_WR_PORT;1329err_info->acpi_rst = "ZRST";1330}13311332static const struct hisi_qm_err_ini hisi_zip_err_ini = {1333.hw_init = hisi_zip_set_user_domain_and_cache,1334.hw_err_enable = hisi_zip_hw_error_enable,1335.hw_err_disable = hisi_zip_hw_error_disable,1336.get_dev_hw_err_status = hisi_zip_get_hw_err_status,1337.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status,1338.open_axi_master_ooo = hisi_zip_open_axi_master_ooo,1339.close_axi_master_ooo = hisi_zip_close_axi_master_ooo,1340.open_sva_prefetch = hisi_zip_open_sva_prefetch,1341.close_sva_prefetch = hisi_zip_close_sva_prefetch,1342.show_last_dfx_regs = hisi_zip_show_last_dfx_regs,1343.err_info_init = hisi_zip_err_info_init,1344.get_err_result = hisi_zip_get_err_result,1345.set_priv_status = hisi_zip_set_priv_status,1346.dev_is_abnormal = hisi_zip_dev_is_abnormal,1347.disable_axi_error = hisi_zip_disable_axi_error,1348.enable_axi_error = hisi_zip_enable_axi_error,1349};13501351static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)1352{1353struct hisi_qm *qm = &hisi_zip->qm;1354struct hisi_zip_ctrl *ctrl;1355int ret;13561357ctrl = devm_kzalloc(&qm->pdev->dev, sizeof(*ctrl), GFP_KERNEL);1358if (!ctrl)1359return -ENOMEM;13601361hisi_zip->ctrl = ctrl;1362ctrl->hisi_zip = hisi_zip;13631364ret = hisi_zip_set_user_domain_and_cache(qm);1365if (ret)1366return ret;13671368hisi_qm_dev_err_init(qm);1369hisi_zip_debug_regs_clear(qm);13701371ret = hisi_zip_show_last_regs_init(qm);1372if (ret)1373pci_err(qm->pdev, "Failed to init last word regs!\n");13741375return ret;1376}13771378static int zip_pre_store_cap_reg(struct hisi_qm *qm)1379{1380struct hisi_qm_cap_record *zip_cap;1381struct pci_dev *pdev = qm->pdev;1382size_t i, size;13831384size = ARRAY_SIZE(zip_cap_query_info);1385zip_cap = devm_kcalloc(&pdev->dev, size, sizeof(*zip_cap), GFP_KERNEL);1386if (!zip_cap)1387return -ENOMEM;13881389for (i = 0; i < size; i++) {1390zip_cap[i].type = zip_cap_query_info[i].type;1391zip_cap[i].name = zip_cap_query_info[i].name;1392zip_cap[i].cap_val = hisi_qm_get_cap_value(qm, zip_cap_query_info,1393i, qm->cap_ver);1394}13951396qm->cap_tables.dev_cap_table = zip_cap;1397qm->cap_tables.dev_cap_size = size;13981399return 0;1400}14011402static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)1403{1404u64 alg_msk;1405int ret;14061407qm->pdev = pdev;1408qm->mode = uacce_mode;1409qm->sqe_size = HZIP_SQE_SIZE;1410qm->dev_name = hisi_zip_name;14111412qm->fun_type = (pdev->device == PCI_DEVICE_ID_HUAWEI_ZIP_PF) ?1413QM_HW_PF : QM_HW_VF;1414if (qm->fun_type == QM_HW_PF) {1415qm->qp_base = HZIP_PF_DEF_Q_BASE;1416qm->qp_num = pf_q_num;1417qm->debug.curr_qm_qp_num = pf_q_num;1418qm->qm_list = &zip_devices;1419qm->err_ini = &hisi_zip_err_ini;1420if (pf_q_num_flag)1421set_bit(QM_MODULE_PARAM, &qm->misc_ctl);1422} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {1423/*1424* have no way to get qm configure in VM in v1 hardware,1425* so currently force PF to uses HZIP_PF_DEF_Q_NUM, and force1426* to trigger only one VF in v1 hardware.1427*1428* v2 hardware has no such problem.1429*/1430qm->qp_base = HZIP_PF_DEF_Q_NUM;1431qm->qp_num = HZIP_QUEUE_NUM_V1 - HZIP_PF_DEF_Q_NUM;1432}14331434ret = hisi_qm_init(qm);1435if (ret) {1436pci_err(qm->pdev, "Failed to init zip qm configures!\n");1437return ret;1438}14391440/* Fetch and save the value of capability registers */1441ret = zip_pre_store_cap_reg(qm);1442if (ret) {1443pci_err(qm->pdev, "Failed to pre-store capability registers!\n");1444goto err_qm_uninit;1445}14461447alg_msk = qm->cap_tables.dev_cap_table[ZIP_ALG_BITMAP].cap_val;1448ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs));1449if (ret) {1450pci_err(qm->pdev, "Failed to set zip algs!\n");1451goto err_qm_uninit;1452}14531454ret = hisi_dae_set_alg(qm);1455if (ret)1456goto err_qm_uninit;14571458return 0;14591460err_qm_uninit:1461hisi_qm_uninit(qm);1462return ret;1463}14641465static void hisi_zip_qm_uninit(struct hisi_qm *qm)1466{1467hisi_qm_uninit(qm);1468}14691470static int hisi_zip_probe_init(struct hisi_zip *hisi_zip)1471{1472u32 type_rate = HZIP_SHAPER_RATE_COMPRESS;1473struct hisi_qm *qm = &hisi_zip->qm;1474int ret;14751476if (qm->fun_type == QM_HW_PF) {1477ret = hisi_zip_pf_probe_init(hisi_zip);1478if (ret)1479return ret;1480/* enable shaper type 0 */1481if (qm->ver >= QM_HW_V3) {1482type_rate |= QM_SHAPER_ENABLE;14831484/* ZIP need to enable shaper type 1 */1485type_rate |= HZIP_SHAPER_RATE_DECOMPRESS << QM_SHAPER_TYPE1_OFFSET;1486qm->type_rate = type_rate;1487}1488}14891490return 0;1491}14921493static void hisi_zip_probe_uninit(struct hisi_qm *qm)1494{1495if (qm->fun_type == QM_HW_VF)1496return;14971498hisi_zip_show_last_regs_uninit(qm);1499hisi_zip_close_sva_prefetch(qm);1500hisi_qm_dev_err_uninit(qm);1501}15021503static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)1504{1505struct hisi_zip *hisi_zip;1506struct hisi_qm *qm;1507int ret;15081509hisi_zip = devm_kzalloc(&pdev->dev, sizeof(*hisi_zip), GFP_KERNEL);1510if (!hisi_zip)1511return -ENOMEM;15121513qm = &hisi_zip->qm;15141515ret = hisi_zip_qm_init(qm, pdev);1516if (ret) {1517pci_err(pdev, "Failed to init ZIP QM (%d)!\n", ret);1518return ret;1519}15201521ret = hisi_zip_probe_init(hisi_zip);1522if (ret) {1523pci_err(pdev, "Failed to probe (%d)!\n", ret);1524goto err_qm_uninit;1525}15261527ret = hisi_qm_start(qm);1528if (ret)1529goto err_probe_uninit;15301531ret = hisi_zip_debugfs_init(qm);1532if (ret)1533pci_err(pdev, "failed to init debugfs (%d)!\n", ret);15341535hisi_qm_add_list(qm, &zip_devices);1536ret = hisi_qm_alg_register(qm, &zip_devices, HZIP_CTX_Q_NUM_DEF);1537if (ret < 0) {1538pci_err(pdev, "failed to register driver to crypto!\n");1539goto err_qm_del_list;1540}15411542if (qm->uacce) {1543ret = uacce_register(qm->uacce);1544if (ret) {1545pci_err(pdev, "failed to register uacce (%d)!\n", ret);1546goto err_qm_alg_unregister;1547}1548}15491550if (qm->fun_type == QM_HW_PF && vfs_num > 0) {1551ret = hisi_qm_sriov_enable(pdev, vfs_num);1552if (ret < 0)1553goto err_qm_alg_unregister;1554}15551556hisi_qm_pm_init(qm);15571558return 0;15591560err_qm_alg_unregister:1561hisi_qm_alg_unregister(qm, &zip_devices, HZIP_CTX_Q_NUM_DEF);15621563err_qm_del_list:1564hisi_qm_del_list(qm, &zip_devices);1565hisi_zip_debugfs_exit(qm);1566hisi_qm_stop(qm, QM_NORMAL);15671568err_probe_uninit:1569hisi_zip_probe_uninit(qm);15701571err_qm_uninit:1572hisi_zip_qm_uninit(qm);15731574return ret;1575}15761577static void hisi_zip_remove(struct pci_dev *pdev)1578{1579struct hisi_qm *qm = pci_get_drvdata(pdev);15801581hisi_qm_pm_uninit(qm);1582hisi_qm_wait_task_finish(qm, &zip_devices);1583hisi_qm_alg_unregister(qm, &zip_devices, HZIP_CTX_Q_NUM_DEF);1584hisi_qm_del_list(qm, &zip_devices);15851586if (qm->fun_type == QM_HW_PF && qm->vfs_num)1587hisi_qm_sriov_disable(pdev, true);15881589hisi_zip_debugfs_exit(qm);1590hisi_qm_stop(qm, QM_NORMAL);1591hisi_zip_probe_uninit(qm);1592hisi_zip_qm_uninit(qm);1593}15941595static const struct dev_pm_ops hisi_zip_pm_ops = {1596SET_RUNTIME_PM_OPS(hisi_qm_suspend, hisi_qm_resume, NULL)1597};15981599static const struct pci_error_handlers hisi_zip_err_handler = {1600.error_detected = hisi_qm_dev_err_detected,1601.slot_reset = hisi_qm_dev_slot_reset,1602.reset_prepare = hisi_qm_reset_prepare,1603.reset_done = hisi_qm_reset_done,1604};16051606static struct pci_driver hisi_zip_pci_driver = {1607.name = "hisi_zip",1608.id_table = hisi_zip_dev_ids,1609.probe = hisi_zip_probe,1610.remove = hisi_zip_remove,1611.sriov_configure = IS_ENABLED(CONFIG_PCI_IOV) ?1612hisi_qm_sriov_configure : NULL,1613.err_handler = &hisi_zip_err_handler,1614.shutdown = hisi_qm_dev_shutdown,1615.driver.pm = &hisi_zip_pm_ops,1616};16171618struct pci_driver *hisi_zip_get_pf_driver(void)1619{1620return &hisi_zip_pci_driver;1621}1622EXPORT_SYMBOL_GPL(hisi_zip_get_pf_driver);16231624static void hisi_zip_register_debugfs(void)1625{1626if (!debugfs_initialized())1627return;16281629hzip_debugfs_root = debugfs_create_dir("hisi_zip", NULL);1630}16311632static void hisi_zip_unregister_debugfs(void)1633{1634debugfs_remove_recursive(hzip_debugfs_root);1635}16361637static int __init hisi_zip_init(void)1638{1639int ret;16401641hisi_qm_init_list(&zip_devices);1642hisi_zip_register_debugfs();16431644ret = pci_register_driver(&hisi_zip_pci_driver);1645if (ret < 0) {1646hisi_zip_unregister_debugfs();1647pr_err("Failed to register pci driver.\n");1648}16491650return ret;1651}16521653static void __exit hisi_zip_exit(void)1654{1655pci_unregister_driver(&hisi_zip_pci_driver);1656hisi_zip_unregister_debugfs();1657}16581659module_init(hisi_zip_init);1660module_exit(hisi_zip_exit);16611662MODULE_LICENSE("GPL v2");1663MODULE_AUTHOR("Zhou Wang <[email protected]>");1664MODULE_DESCRIPTION("Driver for HiSilicon ZIP accelerator");166516661667