SEC_CORE4_ALG_BITMAP_HIGH,
 };
 
+enum sec_cap_reg_record_idx {
+       SEC_DRV_ALG_BITMAP_LOW_IDX = 0x0,
+       SEC_DRV_ALG_BITMAP_HIGH_IDX,
+       SEC_DEV_ALG_BITMAP_LOW_IDX,
+       SEC_DEV_ALG_BITMAP_HIGH_IDX,
+};
+
 void sec_destroy_qps(struct hisi_qp **qps, int qp_num);
 struct hisi_qp **sec_create_qps(void);
 int sec_register_to_crypto(struct hisi_qm *qm);
 
 
 int sec_register_to_crypto(struct hisi_qm *qm)
 {
-       u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW);
+       u64 alg_mask;
        int ret = 0;
 
+       alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX,
+                                     SEC_DRV_ALG_BITMAP_LOW_IDX);
+
        mutex_lock(&sec_algs_lock);
        if (sec_available_devs) {
                sec_available_devs++;
 
 void sec_unregister_from_crypto(struct hisi_qm *qm)
 {
-       u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW);
+       u64 alg_mask;
+
+       alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX,
+                                     SEC_DRV_ALG_BITMAP_LOW_IDX);
 
        mutex_lock(&sec_algs_lock);
        if (--sec_available_devs)
 
        {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF},
 };
 
+static const u32 sec_pre_store_caps[] = {
+       SEC_DRV_ALG_BITMAP_LOW,
+       SEC_DRV_ALG_BITMAP_HIGH,
+       SEC_DEV_ALG_BITMAP_LOW,
+       SEC_DEV_ALG_BITMAP_HIGH,
+};
+
 static const struct qm_dev_alg sec_dev_algs[] = { {
                .alg_msk = SEC_CIPHER_BITMAP,
                .alg = "cipher\n",
 {
        u32 cap_val_h, cap_val_l;
 
-       cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver);
-       cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver);
+       cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val;
+       cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val;
 
        return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l;
 }
        return ret;
 }
 
+static int sec_pre_store_cap_reg(struct hisi_qm *qm)
+{
+       struct hisi_qm_cap_record *sec_cap;
+       struct pci_dev *pdev = qm->pdev;
+       size_t i, size;
+
+       size = ARRAY_SIZE(sec_pre_store_caps);
+       sec_cap = devm_kzalloc(&pdev->dev, sizeof(*sec_cap) * size, GFP_KERNEL);
+       if (!sec_cap)
+               return -ENOMEM;
+
+       for (i = 0; i < size; i++) {
+               sec_cap[i].type = sec_pre_store_caps[i];
+               sec_cap[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info,
+                                    sec_pre_store_caps[i], qm->cap_ver);
+       }
+
+       qm->cap_tables.dev_cap_table = sec_cap;
+
+       return 0;
+}
+
 static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev)
 {
        u64 alg_msk;
                return ret;
        }
 
-       alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW);
+       /* Fetch and save the value of capability registers */
+       ret = sec_pre_store_cap_reg(qm);
+       if (ret) {
+               pci_err(qm->pdev, "Failed to pre-store capability registers!\n");
+               hisi_qm_uninit(qm);
+               return ret;
+       }
+
+       alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX);
        ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs));
        if (ret) {
                pci_err(qm->pdev, "Failed to set sec algs!\n");