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