1/* SPDX-License-Identifier: BSD-3-Clause */ 2/* Copyright(c) 2007-2022 Intel Corporation */ 3#include "adf_accel_devices.h" 4#include "adf_common_drv.h" 5#include "adf_cfg_common.h" 6#include "adf_transport_internal.h" 7#include "icp_qat_hw.h" 8#include "adf_c4xxx_hw_data.h" 9 10#define ADF_C4XXX_PARTTITION_SHIFT 8 11#define ADF_C4XXX_PARTITION(svc, ring) \ 12 ((svc) << ((ring)*ADF_C4XXX_PARTTITION_SHIFT)) 13 14static void 15adf_get_partitions_mask(struct adf_accel_dev *accel_dev, u32 *partitions_mask) 16{ 17 device_t dev = accel_to_pci_dev(accel_dev); 18 u32 enabled_partitions_msk = 0; 19 u8 ring_pair = 0; 20 enum adf_cfg_service_type serv_type = 0; 21 u16 ring_to_svc_map = accel_dev->hw_device->ring_to_svc_map; 22 23 for (ring_pair = 0; ring_pair < ADF_CFG_NUM_SERVICES; ring_pair++) { 24 serv_type = GET_SRV_TYPE(ring_to_svc_map, ring_pair); 25 switch (serv_type) { 26 case CRYPTO: { 27 enabled_partitions_msk |= 28 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_ASYM, 29 ring_pair++); 30 if (ring_pair < ADF_CFG_NUM_SERVICES) 31 enabled_partitions_msk |= 32 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_SYM, 33 ring_pair); 34 else 35 device_printf( 36 dev, "Failed to enable SYM partition.\n"); 37 break; 38 } 39 case COMP: 40 enabled_partitions_msk |= 41 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_DC, ring_pair); 42 break; 43 case SYM: 44 enabled_partitions_msk |= 45 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_SYM, ring_pair); 46 break; 47 case ASYM: 48 enabled_partitions_msk |= 49 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_ASYM, ring_pair); 50 break; 51 default: 52 enabled_partitions_msk |= 53 ADF_C4XXX_PARTITION(ADF_C4XXX_PART_UNUSED, 54 ring_pair); 55 break; 56 } 57 } 58 *partitions_mask = enabled_partitions_msk; 59} 60 61static void 62adf_enable_sym_threads(struct adf_accel_dev *accel_dev, u32 ae, u32 partition) 63{ 64 struct resource *csr = accel_dev->transport->banks[0].csr_addr; 65 const struct adf_ae_info *ae_info = accel_dev->au_info->ae_info; 66 u32 num_sym_thds = ae_info[ae].num_sym_thd; 67 u32 i; 68 u32 part_group = partition / ADF_C4XXX_PARTS_PER_GRP; 69 u32 wkrthd2_partmap = part_group << ADF_C4XXX_PARTS_PER_GRP | 70 (BIT(partition % ADF_C4XXX_PARTS_PER_GRP)); 71 72 for (i = 0; i < num_sym_thds; i++) 73 WRITE_CSR_WQM(csr, 74 ADF_C4XXX_WRKTHD2PARTMAP, 75 (ae * ADF_NUM_THREADS_PER_AE + i), 76 wkrthd2_partmap); 77} 78 79static void 80adf_enable_asym_threads(struct adf_accel_dev *accel_dev, u32 ae, u32 partition) 81{ 82 struct resource *csr = accel_dev->transport->banks[0].csr_addr; 83 const struct adf_ae_info *ae_info = accel_dev->au_info->ae_info; 84 u32 num_asym_thds = ae_info[ae].num_asym_thd; 85 u32 i; 86 u32 part_group = partition / ADF_C4XXX_PARTS_PER_GRP; 87 u32 wkrthd2_partmap = part_group << ADF_C4XXX_PARTS_PER_GRP | 88 (BIT(partition % ADF_C4XXX_PARTS_PER_GRP)); 89 /* For asymmetric cryptography SKU we have one thread less */ 90 u32 num_all_thds = ADF_NUM_THREADS_PER_AE - 2; 91 92 for (i = num_all_thds; i > (num_all_thds - num_asym_thds); i--) 93 WRITE_CSR_WQM(csr, 94 ADF_C4XXX_WRKTHD2PARTMAP, 95 (ae * ADF_NUM_THREADS_PER_AE + i), 96 wkrthd2_partmap); 97} 98 99static void 100adf_enable_dc_threads(struct adf_accel_dev *accel_dev, u32 ae, u32 partition) 101{ 102 struct resource *csr = accel_dev->transport->banks[0].csr_addr; 103 const struct adf_ae_info *ae_info = accel_dev->au_info->ae_info; 104 u32 num_dc_thds = ae_info[ae].num_dc_thd; 105 u32 i; 106 u32 part_group = partition / ADF_C4XXX_PARTS_PER_GRP; 107 u32 wkrthd2_partmap = part_group << ADF_C4XXX_PARTS_PER_GRP | 108 (BIT(partition % ADF_C4XXX_PARTS_PER_GRP)); 109 110 for (i = 0; i < num_dc_thds; i++) 111 WRITE_CSR_WQM(csr, 112 ADF_C4XXX_WRKTHD2PARTMAP, 113 (ae * ADF_NUM_THREADS_PER_AE + i), 114 wkrthd2_partmap); 115} 116 117/* Initialise Resource partitioning. 118 * Initialise a default set of 4 partitions to arbitrate 119 * request rings per bundle. 120 */ 121int 122adf_init_arb_c4xxx(struct adf_accel_dev *accel_dev) 123{ 124 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 125 struct resource *csr = accel_dev->transport->banks[0].csr_addr; 126 struct adf_accel_unit_info *au_info = accel_dev->au_info; 127 u32 i; 128 unsigned long ae_mask; 129 u32 partitions_mask = 0; 130 131 /* invoke common adf_init_arb */ 132 adf_init_arb(accel_dev); 133 134 adf_get_partitions_mask(accel_dev, &partitions_mask); 135 for (i = 0; i < hw_data->num_banks; i++) 136 WRITE_CSR_WQM(csr, 137 ADF_C4XXX_PARTITION_LUT_OFFSET, 138 i, 139 partitions_mask); 140 141 ae_mask = hw_data->ae_mask; 142 143 /* Assigning default partitions to accel engine 144 * worker threads 145 */ 146 for_each_set_bit(i, &ae_mask, ADF_C4XXX_MAX_ACCELENGINES) 147 { 148 if (BIT(i) & au_info->sym_ae_msk) 149 adf_enable_sym_threads(accel_dev, 150 i, 151 ADF_C4XXX_PART_SYM); 152 if (BIT(i) & au_info->asym_ae_msk) 153 adf_enable_asym_threads(accel_dev, 154 i, 155 ADF_C4XXX_PART_ASYM); 156 if (BIT(i) & au_info->dc_ae_msk) 157 adf_enable_dc_threads(accel_dev, i, ADF_C4XXX_PART_DC); 158 } 159 160 return 0; 161} 162 163/* Disable the resource partitioning feature 164 * and restore the default partitioning scheme 165 */ 166void 167adf_exit_arb_c4xxx(struct adf_accel_dev *accel_dev) 168{ 169 struct adf_hw_device_data *hw_data = accel_dev->hw_device; 170 struct resource *csr; 171 u32 i; 172 unsigned long ae_mask; 173 174 if (!accel_dev->transport) 175 return; 176 csr = accel_dev->transport->banks[0].csr_addr; 177 178 /* Restore the default partitionLUT registers */ 179 for (i = 0; i < hw_data->num_banks; i++) 180 WRITE_CSR_WQM(csr, 181 ADF_C4XXX_PARTITION_LUT_OFFSET, 182 i, 183 ADF_C4XXX_DEFAULT_PARTITIONS); 184 185 ae_mask = hw_data->ae_mask; 186 187 /* Reset worker thread to partition mapping */ 188 for (i = 0; i < hw_data->num_engines * ADF_NUM_THREADS_PER_AE; i++) { 189 if (!test_bit((u32)(i / ADF_NUM_THREADS_PER_AE), &ae_mask)) 190 continue; 191 192 WRITE_CSR_WQM(csr, ADF_C4XXX_WRKTHD2PARTMAP, i, 0); 193 } 194} 195