xref: /freebsd/sys/dev/qat/qat_common/adf_hw_arbiter.c (revision c7a063741720ef81d4caa4613242579d12f1d605)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "qat_freebsd.h"
5 #include "adf_cfg.h"
6 #include "adf_common_drv.h"
7 #include "adf_accel_devices.h"
8 #include "icp_qat_uclo.h"
9 #include "icp_qat_fw.h"
10 #include "icp_qat_fw_init_admin.h"
11 #include "adf_cfg_strings.h"
12 #include "adf_transport_access_macros.h"
13 #include "adf_transport_internal.h"
14 #include "adf_accel_devices.h"
15 #include "adf_common_drv.h"
16 #include "adf_transport_internal.h"
17 
18 #define ADF_ARB_NUM 4
19 #define ADF_ARB_REG_SIZE 0x4
20 #define ADF_ARB_WTR_SIZE 0x20
21 #define ADF_ARB_OFFSET 0x30000
22 #define ADF_ARB_REG_SLOT 0x1000
23 #define ADF_ARB_WTR_OFFSET 0x010
24 #define ADF_ARB_RO_EN_OFFSET 0x090
25 #define ADF_ARB_WQCFG_OFFSET 0x100
26 #define ADF_ARB_WRK_2_SER_MAP_OFFSET 0x180
27 #define ADF_ARB_RINGSRVARBEN_OFFSET 0x19C
28 
29 #define WRITE_CSR_ARB_RINGSRVARBEN(csr_addr, index, value)                     \
30 	ADF_CSR_WR(csr_addr,                                                   \
31 		   ADF_ARB_RINGSRVARBEN_OFFSET + (ADF_ARB_REG_SLOT * (index)), \
32 		   value)
33 
34 #define WRITE_CSR_ARB_SARCONFIG(csr_addr, csr_offset, index, value)            \
35 	ADF_CSR_WR(csr_addr, (csr_offset) + (ADF_ARB_REG_SIZE * (index)), value)
36 #define READ_CSR_ARB_RINGSRVARBEN(csr_addr, index)                             \
37 	ADF_CSR_RD(csr_addr,                                                   \
38 		   ADF_ARB_RINGSRVARBEN_OFFSET + (ADF_ARB_REG_SLOT * (index)))
39 
40 static DEFINE_MUTEX(csr_arb_lock);
41 
42 #define WRITE_CSR_ARB_WRK_2_SER_MAP(                                           \
43     csr_addr, csr_offset, wrk_to_ser_map_offset, index, value)                 \
44 	ADF_CSR_WR(csr_addr,                                                   \
45 		   ((csr_offset) + (wrk_to_ser_map_offset)) +                  \
46 		       (ADF_ARB_REG_SIZE * (index)),                           \
47 		   value)
48 
49 int
50 adf_init_arb(struct adf_accel_dev *accel_dev)
51 {
52 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
53 	struct arb_info info;
54 	struct resource *csr = accel_dev->transport->banks[0].csr_addr;
55 	u32 arb_cfg = 0x1 << 31 | 0x4 << 4 | 0x1;
56 	u32 arb;
57 
58 	hw_data->get_arb_info(&info);
59 
60 	/* Service arb configured for 32 bytes responses and
61 	 * ring flow control check enabled.
62 	 */
63 	for (arb = 0; arb < ADF_ARB_NUM; arb++)
64 		WRITE_CSR_ARB_SARCONFIG(csr, info.arbiter_offset, arb, arb_cfg);
65 
66 	return 0;
67 }
68 
69 int
70 adf_init_gen2_arb(struct adf_accel_dev *accel_dev)
71 {
72 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
73 	struct arb_info info;
74 	struct resource *csr = accel_dev->transport->banks[0].csr_addr;
75 	u32 i;
76 	const u32 *thd_2_arb_cfg;
77 
78 	/* invoke common adf_init_arb */
79 	adf_init_arb(accel_dev);
80 
81 	hw_data->get_arb_info(&info);
82 
83 	/* Map worker threads to service arbiters */
84 	hw_data->get_arb_mapping(accel_dev, &thd_2_arb_cfg);
85 	if (!thd_2_arb_cfg)
86 		return EFAULT;
87 
88 	for (i = 0; i < hw_data->num_engines; i++)
89 		WRITE_CSR_ARB_WRK_2_SER_MAP(csr,
90 					    info.arbiter_offset,
91 					    info.wrk_thd_2_srv_arb_map,
92 					    i,
93 					    *(thd_2_arb_cfg + i));
94 	return 0;
95 }
96 
97 void
98 adf_update_ring_arb(struct adf_etr_ring_data *ring)
99 {
100 	WRITE_CSR_ARB_RINGSRVARBEN(ring->bank->csr_addr,
101 				   ring->bank->bank_number,
102 				   ring->bank->ring_mask & 0xFF);
103 }
104 
105 void
106 adf_enable_ring_arb(void *csr_addr, unsigned int bank_nr, unsigned int mask)
107 {
108 	struct resource *csr = csr_addr;
109 	u32 arbenable;
110 
111 	if (!csr)
112 		return;
113 
114 	mutex_lock(&csr_arb_lock);
115 	arbenable = READ_CSR_ARB_RINGSRVARBEN(csr, bank_nr);
116 	arbenable |= mask & 0xFF;
117 	WRITE_CSR_ARB_RINGSRVARBEN(csr, bank_nr, arbenable);
118 
119 	mutex_unlock(&csr_arb_lock);
120 }
121 
122 void
123 adf_disable_ring_arb(void *csr_addr, unsigned int bank_nr, unsigned int mask)
124 {
125 	struct resource *csr = csr_addr;
126 	u32 arbenable;
127 
128 	if (!csr_addr)
129 		return;
130 
131 	mutex_lock(&csr_arb_lock);
132 	arbenable = READ_CSR_ARB_RINGSRVARBEN(csr, bank_nr);
133 	arbenable &= ~mask & 0xFF;
134 	WRITE_CSR_ARB_RINGSRVARBEN(csr, bank_nr, arbenable);
135 	mutex_unlock(&csr_arb_lock);
136 }
137 
138 void
139 adf_exit_arb(struct adf_accel_dev *accel_dev)
140 {
141 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
142 	struct arb_info info;
143 	struct resource *csr;
144 	unsigned int i;
145 
146 	if (!accel_dev->transport)
147 		return;
148 
149 	csr = accel_dev->transport->banks[0].csr_addr;
150 
151 	hw_data->get_arb_info(&info);
152 
153 	/* Reset arbiter configuration */
154 	for (i = 0; i < ADF_ARB_NUM; i++)
155 		WRITE_CSR_ARB_SARCONFIG(csr, info.arbiter_offset, i, 0);
156 
157 	/* Unmap worker threads to service arbiters */
158 	if (hw_data->get_arb_mapping) {
159 		for (i = 0; i < hw_data->num_engines; i++)
160 			WRITE_CSR_ARB_WRK_2_SER_MAP(csr,
161 						    info.arbiter_offset,
162 						    info.wrk_thd_2_srv_arb_map,
163 						    i,
164 						    0);
165 	}
166 
167 	/* Disable arbitration on all rings */
168 	for (i = 0; i < GET_MAX_BANKS(accel_dev); i++)
169 		WRITE_CSR_ARB_RINGSRVARBEN(csr, i, 0);
170 }
171 
172 void
173 adf_disable_arb(struct adf_accel_dev *accel_dev)
174 {
175 	struct resource *csr;
176 	unsigned int i;
177 
178 	if (!accel_dev || !accel_dev->transport)
179 		return;
180 
181 	csr = accel_dev->transport->banks[0].csr_addr;
182 
183 	/* Disable arbitration on all rings */
184 	for (i = 0; i < GET_MAX_BANKS(accel_dev); i++)
185 		WRITE_CSR_ARB_RINGSRVARBEN(csr, i, 0);
186 }
187