xref: /freebsd/sys/dev/qat/qat_common/adf_hw_arbiter.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
278ee8d1cSJulian Grajkowski /* Copyright(c) 2007-2022 Intel Corporation */
378ee8d1cSJulian Grajkowski #include "qat_freebsd.h"
478ee8d1cSJulian Grajkowski #include "adf_cfg.h"
578ee8d1cSJulian Grajkowski #include "adf_common_drv.h"
678ee8d1cSJulian Grajkowski #include "adf_accel_devices.h"
778ee8d1cSJulian Grajkowski #include "icp_qat_uclo.h"
878ee8d1cSJulian Grajkowski #include "icp_qat_fw.h"
978ee8d1cSJulian Grajkowski #include "icp_qat_fw_init_admin.h"
1078ee8d1cSJulian Grajkowski #include "adf_cfg_strings.h"
1178ee8d1cSJulian Grajkowski #include "adf_transport_access_macros.h"
1278ee8d1cSJulian Grajkowski #include "adf_transport_internal.h"
1378ee8d1cSJulian Grajkowski #include "adf_accel_devices.h"
1478ee8d1cSJulian Grajkowski #include "adf_common_drv.h"
1578ee8d1cSJulian Grajkowski #include "adf_transport_internal.h"
1678ee8d1cSJulian Grajkowski 
1778ee8d1cSJulian Grajkowski #define ADF_ARB_NUM 4
1878ee8d1cSJulian Grajkowski #define ADF_ARB_REG_SIZE 0x4
1978ee8d1cSJulian Grajkowski #define ADF_ARB_WTR_SIZE 0x20
2078ee8d1cSJulian Grajkowski #define ADF_ARB_OFFSET 0x30000
2178ee8d1cSJulian Grajkowski #define ADF_ARB_REG_SLOT 0x1000
2278ee8d1cSJulian Grajkowski #define ADF_ARB_WTR_OFFSET 0x010
2378ee8d1cSJulian Grajkowski #define ADF_ARB_RO_EN_OFFSET 0x090
2478ee8d1cSJulian Grajkowski #define ADF_ARB_WQCFG_OFFSET 0x100
2578ee8d1cSJulian Grajkowski #define ADF_ARB_WRK_2_SER_MAP_OFFSET 0x180
2678ee8d1cSJulian Grajkowski #define ADF_ARB_RINGSRVARBEN_OFFSET 0x19C
2778ee8d1cSJulian Grajkowski 
2878ee8d1cSJulian Grajkowski #define WRITE_CSR_ARB_RINGSRVARBEN(csr_addr, index, value)                     \
2978ee8d1cSJulian Grajkowski 	ADF_CSR_WR(csr_addr,                                                   \
3078ee8d1cSJulian Grajkowski 		   ADF_ARB_RINGSRVARBEN_OFFSET + (ADF_ARB_REG_SLOT * (index)), \
3178ee8d1cSJulian Grajkowski 		   value)
3278ee8d1cSJulian Grajkowski 
3378ee8d1cSJulian Grajkowski #define WRITE_CSR_ARB_SARCONFIG(csr_addr, csr_offset, index, value)            \
3478ee8d1cSJulian Grajkowski 	ADF_CSR_WR(csr_addr, (csr_offset) + (ADF_ARB_REG_SIZE * (index)), value)
3578ee8d1cSJulian Grajkowski #define READ_CSR_ARB_RINGSRVARBEN(csr_addr, index)                             \
3678ee8d1cSJulian Grajkowski 	ADF_CSR_RD(csr_addr,                                                   \
3778ee8d1cSJulian Grajkowski 		   ADF_ARB_RINGSRVARBEN_OFFSET + (ADF_ARB_REG_SLOT * (index)))
3878ee8d1cSJulian Grajkowski 
3978ee8d1cSJulian Grajkowski static DEFINE_MUTEX(csr_arb_lock);
4078ee8d1cSJulian Grajkowski 
4178ee8d1cSJulian Grajkowski #define WRITE_CSR_ARB_WRK_2_SER_MAP(                                           \
4278ee8d1cSJulian Grajkowski     csr_addr, csr_offset, wrk_to_ser_map_offset, index, value)                 \
4378ee8d1cSJulian Grajkowski 	ADF_CSR_WR(csr_addr,                                                   \
4478ee8d1cSJulian Grajkowski 		   ((csr_offset) + (wrk_to_ser_map_offset)) +                  \
4578ee8d1cSJulian Grajkowski 		       (ADF_ARB_REG_SIZE * (index)),                           \
4678ee8d1cSJulian Grajkowski 		   value)
4778ee8d1cSJulian Grajkowski 
4878ee8d1cSJulian Grajkowski int
adf_init_arb(struct adf_accel_dev * accel_dev)4978ee8d1cSJulian Grajkowski adf_init_arb(struct adf_accel_dev *accel_dev)
5078ee8d1cSJulian Grajkowski {
5178ee8d1cSJulian Grajkowski 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
5278ee8d1cSJulian Grajkowski 	struct arb_info info;
5378ee8d1cSJulian Grajkowski 	struct resource *csr = accel_dev->transport->banks[0].csr_addr;
5478ee8d1cSJulian Grajkowski 	u32 arb_cfg = 0x1 << 31 | 0x4 << 4 | 0x1;
5578ee8d1cSJulian Grajkowski 	u32 arb;
5678ee8d1cSJulian Grajkowski 
5778ee8d1cSJulian Grajkowski 	hw_data->get_arb_info(&info);
5878ee8d1cSJulian Grajkowski 
5978ee8d1cSJulian Grajkowski 	/* Service arb configured for 32 bytes responses and
6078ee8d1cSJulian Grajkowski 	 * ring flow control check enabled.
6178ee8d1cSJulian Grajkowski 	 */
6278ee8d1cSJulian Grajkowski 	for (arb = 0; arb < ADF_ARB_NUM; arb++)
6378ee8d1cSJulian Grajkowski 		WRITE_CSR_ARB_SARCONFIG(csr, info.arbiter_offset, arb, arb_cfg);
6478ee8d1cSJulian Grajkowski 
6578ee8d1cSJulian Grajkowski 	return 0;
6678ee8d1cSJulian Grajkowski }
6778ee8d1cSJulian Grajkowski 
6878ee8d1cSJulian Grajkowski int
adf_init_gen2_arb(struct adf_accel_dev * accel_dev)6978ee8d1cSJulian Grajkowski adf_init_gen2_arb(struct adf_accel_dev *accel_dev)
7078ee8d1cSJulian Grajkowski {
7178ee8d1cSJulian Grajkowski 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
7278ee8d1cSJulian Grajkowski 	struct arb_info info;
7378ee8d1cSJulian Grajkowski 	struct resource *csr = accel_dev->transport->banks[0].csr_addr;
7478ee8d1cSJulian Grajkowski 	u32 i;
7578ee8d1cSJulian Grajkowski 	const u32 *thd_2_arb_cfg;
7678ee8d1cSJulian Grajkowski 
7778ee8d1cSJulian Grajkowski 	/* invoke common adf_init_arb */
7878ee8d1cSJulian Grajkowski 	adf_init_arb(accel_dev);
7978ee8d1cSJulian Grajkowski 
8078ee8d1cSJulian Grajkowski 	hw_data->get_arb_info(&info);
8178ee8d1cSJulian Grajkowski 
8278ee8d1cSJulian Grajkowski 	/* Map worker threads to service arbiters */
8378ee8d1cSJulian Grajkowski 	hw_data->get_arb_mapping(accel_dev, &thd_2_arb_cfg);
8478ee8d1cSJulian Grajkowski 	if (!thd_2_arb_cfg)
8578ee8d1cSJulian Grajkowski 		return EFAULT;
8678ee8d1cSJulian Grajkowski 
8778ee8d1cSJulian Grajkowski 	for (i = 0; i < hw_data->num_engines; i++)
8878ee8d1cSJulian Grajkowski 		WRITE_CSR_ARB_WRK_2_SER_MAP(csr,
8978ee8d1cSJulian Grajkowski 					    info.arbiter_offset,
9078ee8d1cSJulian Grajkowski 					    info.wrk_thd_2_srv_arb_map,
9178ee8d1cSJulian Grajkowski 					    i,
9278ee8d1cSJulian Grajkowski 					    *(thd_2_arb_cfg + i));
9378ee8d1cSJulian Grajkowski 	return 0;
9478ee8d1cSJulian Grajkowski }
9578ee8d1cSJulian Grajkowski 
9678ee8d1cSJulian Grajkowski void
adf_update_ring_arb(struct adf_etr_ring_data * ring)9778ee8d1cSJulian Grajkowski adf_update_ring_arb(struct adf_etr_ring_data *ring)
9878ee8d1cSJulian Grajkowski {
99a977168cSMichal Gulbicki 	int shift;
100a977168cSMichal Gulbicki 	u32 arben, arben_tx, arben_rx, arb_mask;
101a977168cSMichal Gulbicki 	struct adf_accel_dev *accel_dev = ring->bank->accel_dev;
102a977168cSMichal Gulbicki 	struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info;
103a977168cSMichal Gulbicki 	struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops;
104a977168cSMichal Gulbicki 
105a977168cSMichal Gulbicki 	arb_mask = csr_info->arb_enable_mask;
106a977168cSMichal Gulbicki 	shift = hweight32(arb_mask);
107a977168cSMichal Gulbicki 
108a977168cSMichal Gulbicki 	arben_tx = ring->bank->ring_mask & arb_mask;
109a977168cSMichal Gulbicki 	arben_rx = (ring->bank->ring_mask >> shift) & arb_mask;
110a977168cSMichal Gulbicki 	arben = arben_tx & arben_rx;
111a977168cSMichal Gulbicki 	csr_ops->write_csr_ring_srv_arb_en(ring->bank->csr_addr,
11278ee8d1cSJulian Grajkowski 					   ring->bank->bank_number,
113a977168cSMichal Gulbicki 					   arben);
11478ee8d1cSJulian Grajkowski }
11578ee8d1cSJulian Grajkowski 
11678ee8d1cSJulian Grajkowski void
adf_update_uio_ring_arb(struct adf_uio_control_bundle * bundle)117*266b0663SKrzysztof Zdziarski adf_update_uio_ring_arb(struct adf_uio_control_bundle *bundle)
118*266b0663SKrzysztof Zdziarski {
119*266b0663SKrzysztof Zdziarski 	int shift;
120*266b0663SKrzysztof Zdziarski 	u32 arben, arben_tx, arben_rx, arb_mask;
121*266b0663SKrzysztof Zdziarski 	struct adf_accel_dev *accel_dev = bundle->uio_priv.accel->accel_dev;
122*266b0663SKrzysztof Zdziarski 	struct adf_hw_csr_info *csr_info = &accel_dev->hw_device->csr_info;
123*266b0663SKrzysztof Zdziarski 	struct adf_hw_csr_ops *csr_ops = &csr_info->csr_ops;
124*266b0663SKrzysztof Zdziarski 
125*266b0663SKrzysztof Zdziarski 	arb_mask = csr_info->arb_enable_mask;
126*266b0663SKrzysztof Zdziarski 	shift = hweight32(arb_mask);
127*266b0663SKrzysztof Zdziarski 
128*266b0663SKrzysztof Zdziarski 	arben_tx = bundle->rings_enabled & arb_mask;
129*266b0663SKrzysztof Zdziarski 	arben_rx = (bundle->rings_enabled >> shift) & arb_mask;
130*266b0663SKrzysztof Zdziarski 	arben = arben_tx & arben_rx;
131*266b0663SKrzysztof Zdziarski 	csr_ops->write_csr_ring_srv_arb_en(bundle->csr_addr,
132*266b0663SKrzysztof Zdziarski 					   bundle->hardware_bundle_number,
133*266b0663SKrzysztof Zdziarski 					   arben);
134*266b0663SKrzysztof Zdziarski }
135*266b0663SKrzysztof Zdziarski void
adf_enable_ring_arb(struct adf_accel_dev * accel_dev,void * csr_addr,unsigned int bank_nr,unsigned int mask)136a977168cSMichal Gulbicki adf_enable_ring_arb(struct adf_accel_dev *accel_dev,
137a977168cSMichal Gulbicki 		    void *csr_addr,
138a977168cSMichal Gulbicki 		    unsigned int bank_nr,
139a977168cSMichal Gulbicki 		    unsigned int mask)
14078ee8d1cSJulian Grajkowski {
141a977168cSMichal Gulbicki 	struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev);
14278ee8d1cSJulian Grajkowski 	u32 arbenable;
14378ee8d1cSJulian Grajkowski 
144*266b0663SKrzysztof Zdziarski 	if (!csr_addr)
14578ee8d1cSJulian Grajkowski 		return;
14678ee8d1cSJulian Grajkowski 
14778ee8d1cSJulian Grajkowski 	mutex_lock(&csr_arb_lock);
148*266b0663SKrzysztof Zdziarski 	arbenable = csr_ops->read_csr_ring_srv_arb_en(csr_addr, bank_nr);
14978ee8d1cSJulian Grajkowski 	arbenable |= mask & 0xFF;
150*266b0663SKrzysztof Zdziarski 	csr_ops->write_csr_ring_srv_arb_en(csr_addr, bank_nr, arbenable);
15178ee8d1cSJulian Grajkowski 
15278ee8d1cSJulian Grajkowski 	mutex_unlock(&csr_arb_lock);
15378ee8d1cSJulian Grajkowski }
15478ee8d1cSJulian Grajkowski 
15578ee8d1cSJulian Grajkowski void
adf_disable_ring_arb(struct adf_accel_dev * accel_dev,void * csr_addr,unsigned int bank_nr,unsigned int mask)156a977168cSMichal Gulbicki adf_disable_ring_arb(struct adf_accel_dev *accel_dev,
157a977168cSMichal Gulbicki 		     void *csr_addr,
158a977168cSMichal Gulbicki 		     unsigned int bank_nr,
159a977168cSMichal Gulbicki 		     unsigned int mask)
16078ee8d1cSJulian Grajkowski {
161a977168cSMichal Gulbicki 	struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev);
16278ee8d1cSJulian Grajkowski 	struct resource *csr = csr_addr;
16378ee8d1cSJulian Grajkowski 	u32 arbenable;
16478ee8d1cSJulian Grajkowski 
16578ee8d1cSJulian Grajkowski 	if (!csr_addr)
16678ee8d1cSJulian Grajkowski 		return;
16778ee8d1cSJulian Grajkowski 
16878ee8d1cSJulian Grajkowski 	mutex_lock(&csr_arb_lock);
169a977168cSMichal Gulbicki 	arbenable = csr_ops->read_csr_ring_srv_arb_en(csr, bank_nr);
17078ee8d1cSJulian Grajkowski 	arbenable &= ~mask & 0xFF;
171a977168cSMichal Gulbicki 	csr_ops->write_csr_ring_srv_arb_en(csr, bank_nr, arbenable);
17278ee8d1cSJulian Grajkowski 	mutex_unlock(&csr_arb_lock);
17378ee8d1cSJulian Grajkowski }
17478ee8d1cSJulian Grajkowski 
17578ee8d1cSJulian Grajkowski void
adf_exit_arb(struct adf_accel_dev * accel_dev)17678ee8d1cSJulian Grajkowski adf_exit_arb(struct adf_accel_dev *accel_dev)
17778ee8d1cSJulian Grajkowski {
178a977168cSMichal Gulbicki 	struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(accel_dev);
17978ee8d1cSJulian Grajkowski 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
18078ee8d1cSJulian Grajkowski 	struct arb_info info;
18178ee8d1cSJulian Grajkowski 	struct resource *csr;
18278ee8d1cSJulian Grajkowski 	unsigned int i;
18378ee8d1cSJulian Grajkowski 
18478ee8d1cSJulian Grajkowski 	if (!accel_dev->transport)
18578ee8d1cSJulian Grajkowski 		return;
18678ee8d1cSJulian Grajkowski 
18778ee8d1cSJulian Grajkowski 	csr = accel_dev->transport->banks[0].csr_addr;
18878ee8d1cSJulian Grajkowski 
18978ee8d1cSJulian Grajkowski 	hw_data->get_arb_info(&info);
19078ee8d1cSJulian Grajkowski 
19178ee8d1cSJulian Grajkowski 	/* Reset arbiter configuration */
19278ee8d1cSJulian Grajkowski 	for (i = 0; i < ADF_ARB_NUM; i++)
19378ee8d1cSJulian Grajkowski 		WRITE_CSR_ARB_SARCONFIG(csr, info.arbiter_offset, i, 0);
19478ee8d1cSJulian Grajkowski 
19578ee8d1cSJulian Grajkowski 	/* Unmap worker threads to service arbiters */
19678ee8d1cSJulian Grajkowski 	if (hw_data->get_arb_mapping) {
19778ee8d1cSJulian Grajkowski 		for (i = 0; i < hw_data->num_engines; i++)
19878ee8d1cSJulian Grajkowski 			WRITE_CSR_ARB_WRK_2_SER_MAP(csr,
19978ee8d1cSJulian Grajkowski 						    info.arbiter_offset,
20078ee8d1cSJulian Grajkowski 						    info.wrk_thd_2_srv_arb_map,
20178ee8d1cSJulian Grajkowski 						    i,
20278ee8d1cSJulian Grajkowski 						    0);
20378ee8d1cSJulian Grajkowski 	}
20478ee8d1cSJulian Grajkowski 
20578ee8d1cSJulian Grajkowski 	/* Disable arbitration on all rings */
20678ee8d1cSJulian Grajkowski 	for (i = 0; i < GET_MAX_BANKS(accel_dev); i++)
207a977168cSMichal Gulbicki 		csr_ops->write_csr_ring_srv_arb_en(csr, i, 0);
20878ee8d1cSJulian Grajkowski }
20978ee8d1cSJulian Grajkowski 
21078ee8d1cSJulian Grajkowski void
adf_disable_arb(struct adf_accel_dev * accel_dev)21178ee8d1cSJulian Grajkowski adf_disable_arb(struct adf_accel_dev *accel_dev)
21278ee8d1cSJulian Grajkowski {
213c0a4a7bbSKrzysztof Zdziarski 	struct adf_hw_csr_ops *csr_ops;
21478ee8d1cSJulian Grajkowski 	struct resource *csr;
21578ee8d1cSJulian Grajkowski 	unsigned int i;
21678ee8d1cSJulian Grajkowski 
21778ee8d1cSJulian Grajkowski 	if (!accel_dev || !accel_dev->transport)
21878ee8d1cSJulian Grajkowski 		return;
21978ee8d1cSJulian Grajkowski 
22078ee8d1cSJulian Grajkowski 	csr = accel_dev->transport->banks[0].csr_addr;
221c0a4a7bbSKrzysztof Zdziarski 	csr_ops = GET_CSR_OPS(accel_dev);
22278ee8d1cSJulian Grajkowski 
22378ee8d1cSJulian Grajkowski 	/* Disable arbitration on all rings */
22478ee8d1cSJulian Grajkowski 	for (i = 0; i < GET_MAX_BANKS(accel_dev); i++)
225a977168cSMichal Gulbicki 		csr_ops->write_csr_ring_srv_arb_en(csr, i, 0);
22678ee8d1cSJulian Grajkowski }
227