1 /*
2   This file is provided under a dual BSD/GPLv2 license.  When using or
3   redistributing this file, you may do so under either license.
4 
5   GPL LICENSE SUMMARY
6   Copyright(c) 2014 Intel Corporation.
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of version 2 of the GNU General Public License as
9   published by the Free Software Foundation.
10 
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   General Public License for more details.
15 
16   Contact Information:
17   qat-linux@intel.com
18 
19   BSD LICENSE
20   Copyright(c) 2014 Intel Corporation.
21   Redistribution and use in source and binary forms, with or without
22   modification, are permitted provided that the following conditions
23   are met:
24 
25 	* Redistributions of source code must retain the above copyright
26 	  notice, this list of conditions and the following disclaimer.
27 	* Redistributions in binary form must reproduce the above copyright
28 	  notice, this list of conditions and the following disclaimer in
29 	  the documentation and/or other materials provided with the
30 	  distribution.
31 	* Neither the name of Intel Corporation nor the names of its
32 	  contributors may be used to endorse or promote products derived
33 	  from this software without specific prior written permission.
34 
35   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 */
47 #include <adf_accel_devices.h>
48 #include <adf_common_drv.h>
49 #include <adf_pf2vf_msg.h>
50 #include "adf_c3xxx_hw_data.h"
51 
52 /* Worker thread to service arbiter mappings based on dev SKUs */
53 static const u32 thrd_to_arb_map_6_me_sku[] = {
54 	0x12222AAA, 0x11222AAA, 0x12222AAA,
55 	0x11222AAA, 0x12222AAA, 0x11222AAA
56 };
57 
58 static struct adf_hw_device_class c3xxx_class = {
59 	.name = ADF_C3XXX_DEVICE_NAME,
60 	.type = DEV_C3XXX,
61 	.instances = 0
62 };
63 
get_accel_mask(u32 fuse)64 static u32 get_accel_mask(u32 fuse)
65 {
66 	return (~fuse) >> ADF_C3XXX_ACCELERATORS_REG_OFFSET &
67 		ADF_C3XXX_ACCELERATORS_MASK;
68 }
69 
get_ae_mask(u32 fuse)70 static u32 get_ae_mask(u32 fuse)
71 {
72 	return (~fuse) & ADF_C3XXX_ACCELENGINES_MASK;
73 }
74 
get_num_accels(struct adf_hw_device_data * self)75 static u32 get_num_accels(struct adf_hw_device_data *self)
76 {
77 	u32 i, ctr = 0;
78 
79 	if (!self || !self->accel_mask)
80 		return 0;
81 
82 	for (i = 0; i < ADF_C3XXX_MAX_ACCELERATORS; i++) {
83 		if (self->accel_mask & (1 << i))
84 			ctr++;
85 	}
86 	return ctr;
87 }
88 
get_num_aes(struct adf_hw_device_data * self)89 static u32 get_num_aes(struct adf_hw_device_data *self)
90 {
91 	u32 i, ctr = 0;
92 
93 	if (!self || !self->ae_mask)
94 		return 0;
95 
96 	for (i = 0; i < ADF_C3XXX_MAX_ACCELENGINES; i++) {
97 		if (self->ae_mask & (1 << i))
98 			ctr++;
99 	}
100 	return ctr;
101 }
102 
get_misc_bar_id(struct adf_hw_device_data * self)103 static u32 get_misc_bar_id(struct adf_hw_device_data *self)
104 {
105 	return ADF_C3XXX_PMISC_BAR;
106 }
107 
get_etr_bar_id(struct adf_hw_device_data * self)108 static u32 get_etr_bar_id(struct adf_hw_device_data *self)
109 {
110 	return ADF_C3XXX_ETR_BAR;
111 }
112 
get_sram_bar_id(struct adf_hw_device_data * self)113 static u32 get_sram_bar_id(struct adf_hw_device_data *self)
114 {
115 	return 0;
116 }
117 
get_sku(struct adf_hw_device_data * self)118 static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
119 {
120 	int aes = get_num_aes(self);
121 
122 	if (aes == 6)
123 		return DEV_SKU_4;
124 
125 	return DEV_SKU_UNKNOWN;
126 }
127 
adf_get_arbiter_mapping(struct adf_accel_dev * accel_dev,u32 const ** arb_map_config)128 static void adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
129 				    u32 const **arb_map_config)
130 {
131 	switch (accel_dev->accel_pci_dev.sku) {
132 	case DEV_SKU_4:
133 		*arb_map_config = thrd_to_arb_map_6_me_sku;
134 		break;
135 	default:
136 		dev_err(&GET_DEV(accel_dev),
137 			"The configuration doesn't match any SKU");
138 		*arb_map_config = NULL;
139 	}
140 }
141 
get_pf2vf_offset(u32 i)142 static u32 get_pf2vf_offset(u32 i)
143 {
144 	return ADF_C3XXX_PF2VF_OFFSET(i);
145 }
146 
get_vintmsk_offset(u32 i)147 static u32 get_vintmsk_offset(u32 i)
148 {
149 	return ADF_C3XXX_VINTMSK_OFFSET(i);
150 }
151 
adf_enable_error_correction(struct adf_accel_dev * accel_dev)152 static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
153 {
154 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
155 	struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR];
156 	void __iomem *csr = misc_bar->virt_addr;
157 	unsigned int val, i;
158 
159 	/* Enable Accel Engine error detection & correction */
160 	for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
161 		val = ADF_CSR_RD(csr, ADF_C3XXX_AE_CTX_ENABLES(i));
162 		val |= ADF_C3XXX_ENABLE_AE_ECC_ERR;
163 		ADF_CSR_WR(csr, ADF_C3XXX_AE_CTX_ENABLES(i), val);
164 		val = ADF_CSR_RD(csr, ADF_C3XXX_AE_MISC_CONTROL(i));
165 		val |= ADF_C3XXX_ENABLE_AE_ECC_PARITY_CORR;
166 		ADF_CSR_WR(csr, ADF_C3XXX_AE_MISC_CONTROL(i), val);
167 	}
168 
169 	/* Enable shared memory error detection & correction */
170 	for (i = 0; i < hw_device->get_num_accels(hw_device); i++) {
171 		val = ADF_CSR_RD(csr, ADF_C3XXX_UERRSSMSH(i));
172 		val |= ADF_C3XXX_ERRSSMSH_EN;
173 		ADF_CSR_WR(csr, ADF_C3XXX_UERRSSMSH(i), val);
174 		val = ADF_CSR_RD(csr, ADF_C3XXX_CERRSSMSH(i));
175 		val |= ADF_C3XXX_ERRSSMSH_EN;
176 		ADF_CSR_WR(csr, ADF_C3XXX_CERRSSMSH(i), val);
177 	}
178 }
179 
adf_enable_ints(struct adf_accel_dev * accel_dev)180 static void adf_enable_ints(struct adf_accel_dev *accel_dev)
181 {
182 	void __iomem *addr;
183 
184 	addr = (&GET_BARS(accel_dev)[ADF_C3XXX_PMISC_BAR])->virt_addr;
185 
186 	/* Enable bundle and misc interrupts */
187 	ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF0_MASK_OFFSET,
188 		   ADF_C3XXX_SMIA0_MASK);
189 	ADF_CSR_WR(addr, ADF_C3XXX_SMIAPF1_MASK_OFFSET,
190 		   ADF_C3XXX_SMIA1_MASK);
191 }
192 
adf_pf_enable_vf2pf_comms(struct adf_accel_dev * accel_dev)193 static int adf_pf_enable_vf2pf_comms(struct adf_accel_dev *accel_dev)
194 {
195 	return 0;
196 }
197 
adf_init_hw_data_c3xxx(struct adf_hw_device_data * hw_data)198 void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data)
199 {
200 	hw_data->dev_class = &c3xxx_class;
201 	hw_data->instance_id = c3xxx_class.instances++;
202 	hw_data->num_banks = ADF_C3XXX_ETR_MAX_BANKS;
203 	hw_data->num_accel = ADF_C3XXX_MAX_ACCELERATORS;
204 	hw_data->num_logical_accel = 1;
205 	hw_data->num_engines = ADF_C3XXX_MAX_ACCELENGINES;
206 	hw_data->tx_rx_gap = ADF_C3XXX_RX_RINGS_OFFSET;
207 	hw_data->tx_rings_mask = ADF_C3XXX_TX_RINGS_MASK;
208 	hw_data->alloc_irq = adf_isr_resource_alloc;
209 	hw_data->free_irq = adf_isr_resource_free;
210 	hw_data->enable_error_correction = adf_enable_error_correction;
211 	hw_data->get_accel_mask = get_accel_mask;
212 	hw_data->get_ae_mask = get_ae_mask;
213 	hw_data->get_num_accels = get_num_accels;
214 	hw_data->get_num_aes = get_num_aes;
215 	hw_data->get_sram_bar_id = get_sram_bar_id;
216 	hw_data->get_etr_bar_id = get_etr_bar_id;
217 	hw_data->get_misc_bar_id = get_misc_bar_id;
218 	hw_data->get_pf2vf_offset = get_pf2vf_offset;
219 	hw_data->get_vintmsk_offset = get_vintmsk_offset;
220 	hw_data->get_sku = get_sku;
221 	hw_data->fw_name = ADF_C3XXX_FW;
222 	hw_data->fw_mmp_name = ADF_C3XXX_MMP;
223 	hw_data->init_admin_comms = adf_init_admin_comms;
224 	hw_data->exit_admin_comms = adf_exit_admin_comms;
225 	hw_data->disable_iov = adf_disable_sriov;
226 	hw_data->send_admin_init = adf_send_admin_init;
227 	hw_data->init_arb = adf_init_arb;
228 	hw_data->exit_arb = adf_exit_arb;
229 	hw_data->get_arb_mapping = adf_get_arbiter_mapping;
230 	hw_data->enable_ints = adf_enable_ints;
231 	hw_data->enable_vf2pf_comms = adf_pf_enable_vf2pf_comms;
232 	hw_data->reset_device = adf_reset_flr;
233 	hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION;
234 }
235 
adf_clean_hw_data_c3xxx(struct adf_hw_device_data * hw_data)236 void adf_clean_hw_data_c3xxx(struct adf_hw_device_data *hw_data)
237 {
238 	hw_data->dev_class->instances--;
239 }
240