1 #include <linux/delay.h>
3 #include "nitrox_dev.h"
4 #include "nitrox_csr.h"
7 * emu_enable_cores - Enable EMU cluster cores.
10 static void emu_enable_cores(struct nitrox_device *ndev)
12 union emu_se_enable emu_se;
13 union emu_ae_enable emu_ae;
16 /* AE cores 20 per cluster */
18 emu_ae.s.enable = 0xfffff;
20 /* SE cores 16 per cluster */
22 emu_se.s.enable = 0xffff;
24 /* enable per cluster cores */
25 for (i = 0; i < NR_CLUSTERS; i++) {
26 nitrox_write_csr(ndev, EMU_AE_ENABLEX(i), emu_ae.value);
27 nitrox_write_csr(ndev, EMU_SE_ENABLEX(i), emu_se.value);
32 * nitrox_config_emu_unit - configure EMU unit.
35 void nitrox_config_emu_unit(struct nitrox_device *ndev)
37 union emu_wd_int_ena_w1s emu_wd_int;
38 union emu_ge_int_ena_w1s emu_ge_int;
43 emu_enable_cores(ndev);
45 /* enable general error and watch dog interrupts */
47 emu_ge_int.s.se_ge = 0xffff;
48 emu_ge_int.s.ae_ge = 0xfffff;
50 emu_wd_int.s.se_wd = 1;
52 for (i = 0; i < NR_CLUSTERS; i++) {
53 offset = EMU_WD_INT_ENA_W1SX(i);
54 nitrox_write_csr(ndev, offset, emu_wd_int.value);
55 offset = EMU_GE_INT_ENA_W1SX(i);
56 nitrox_write_csr(ndev, offset, emu_ge_int.value);
60 static void reset_pkt_input_ring(struct nitrox_device *ndev, int ring)
62 union nps_pkt_in_instr_ctl pkt_in_ctl;
63 union nps_pkt_in_instr_baoff_dbell pkt_in_dbell;
64 union nps_pkt_in_done_cnts pkt_in_cnts;
67 offset = NPS_PKT_IN_INSTR_CTLX(ring);
68 /* disable the ring */
69 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
71 nitrox_write_csr(ndev, offset, pkt_in_ctl.value);
72 usleep_range(100, 150);
74 /* wait to clear [ENB] */
76 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
77 } while (pkt_in_ctl.s.enb);
79 /* clear off door bell counts */
80 offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(ring);
81 pkt_in_dbell.value = 0;
82 pkt_in_dbell.s.dbell = 0xffffffff;
83 nitrox_write_csr(ndev, offset, pkt_in_dbell.value);
85 /* clear done counts */
86 offset = NPS_PKT_IN_DONE_CNTSX(ring);
87 pkt_in_cnts.value = nitrox_read_csr(ndev, offset);
88 nitrox_write_csr(ndev, offset, pkt_in_cnts.value);
89 usleep_range(50, 100);
92 void enable_pkt_input_ring(struct nitrox_device *ndev, int ring)
94 union nps_pkt_in_instr_ctl pkt_in_ctl;
97 /* 64-byte instruction size */
98 offset = NPS_PKT_IN_INSTR_CTLX(ring);
99 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
100 pkt_in_ctl.s.is64b = 1;
101 pkt_in_ctl.s.enb = 1;
102 nitrox_write_csr(ndev, offset, pkt_in_ctl.value);
104 /* wait for set [ENB] */
106 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
107 } while (!pkt_in_ctl.s.enb);
111 * nitrox_config_pkt_input_rings - configure Packet Input Rings
114 void nitrox_config_pkt_input_rings(struct nitrox_device *ndev)
118 for (i = 0; i < ndev->nr_queues; i++) {
119 struct nitrox_cmdq *cmdq = &ndev->pkt_cmdqs[i];
120 union nps_pkt_in_instr_rsize pkt_in_rsize;
123 reset_pkt_input_ring(ndev, i);
125 /* configure ring base address 16-byte aligned,
126 * size and interrupt threshold.
128 offset = NPS_PKT_IN_INSTR_BADDRX(i);
129 nitrox_write_csr(ndev, NPS_PKT_IN_INSTR_BADDRX(i), cmdq->dma);
131 /* configure ring size */
132 offset = NPS_PKT_IN_INSTR_RSIZEX(i);
133 pkt_in_rsize.value = 0;
134 pkt_in_rsize.s.rsize = ndev->qlen;
135 nitrox_write_csr(ndev, offset, pkt_in_rsize.value);
137 /* set high threshold for pkt input ring interrupts */
138 offset = NPS_PKT_IN_INT_LEVELSX(i);
139 nitrox_write_csr(ndev, offset, 0xffffffff);
141 enable_pkt_input_ring(ndev, i);
145 static void reset_pkt_solicit_port(struct nitrox_device *ndev, int port)
147 union nps_pkt_slc_ctl pkt_slc_ctl;
148 union nps_pkt_slc_cnts pkt_slc_cnts;
151 /* disable slc port */
152 offset = NPS_PKT_SLC_CTLX(port);
153 pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
154 pkt_slc_ctl.s.enb = 0;
155 nitrox_write_csr(ndev, offset, pkt_slc_ctl.value);
156 usleep_range(100, 150);
158 /* wait to clear [ENB] */
160 pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
161 } while (pkt_slc_ctl.s.enb);
163 /* clear slc counters */
164 offset = NPS_PKT_SLC_CNTSX(port);
165 pkt_slc_cnts.value = nitrox_read_csr(ndev, offset);
166 nitrox_write_csr(ndev, offset, pkt_slc_cnts.value);
167 usleep_range(50, 100);
170 void enable_pkt_solicit_port(struct nitrox_device *ndev, int port)
172 union nps_pkt_slc_ctl pkt_slc_ctl;
175 offset = NPS_PKT_SLC_CTLX(port);
176 pkt_slc_ctl.value = 0;
177 pkt_slc_ctl.s.enb = 1;
180 * 8 trailing 0x00 bytes will be added
181 * to the end of the outgoing packet.
184 /* enable response header */
185 pkt_slc_ctl.s.rh = 1;
186 nitrox_write_csr(ndev, offset, pkt_slc_ctl.value);
188 /* wait to set [ENB] */
190 pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
191 } while (!pkt_slc_ctl.s.enb);
194 static void config_single_pkt_solicit_port(struct nitrox_device *ndev,
197 union nps_pkt_slc_int_levels pkt_slc_int;
200 reset_pkt_solicit_port(ndev, port);
202 offset = NPS_PKT_SLC_INT_LEVELSX(port);
203 pkt_slc_int.value = 0;
204 /* time interrupt threshold */
205 pkt_slc_int.s.timet = 0x3fffff;
206 nitrox_write_csr(ndev, offset, pkt_slc_int.value);
208 enable_pkt_solicit_port(ndev, port);
211 void nitrox_config_pkt_solicit_ports(struct nitrox_device *ndev)
215 for (i = 0; i < ndev->nr_queues; i++)
216 config_single_pkt_solicit_port(ndev, i);
220 * enable_nps_interrupts - enable NPS interrutps
223 * This includes NPS core, packet in and slc interrupts.
225 static void enable_nps_interrupts(struct nitrox_device *ndev)
227 union nps_core_int_ena_w1s core_int;
229 /* NPS core interrutps */
231 core_int.s.host_wr_err = 1;
232 core_int.s.host_wr_timeout = 1;
233 core_int.s.exec_wr_timeout = 1;
234 core_int.s.npco_dma_malform = 1;
235 core_int.s.host_nps_wr_err = 1;
236 nitrox_write_csr(ndev, NPS_CORE_INT_ENA_W1S, core_int.value);
238 /* NPS packet in ring interrupts */
239 nitrox_write_csr(ndev, NPS_PKT_IN_RERR_LO_ENA_W1S, (~0ULL));
240 nitrox_write_csr(ndev, NPS_PKT_IN_RERR_HI_ENA_W1S, (~0ULL));
241 nitrox_write_csr(ndev, NPS_PKT_IN_ERR_TYPE_ENA_W1S, (~0ULL));
242 /* NPS packet slc port interrupts */
243 nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_HI_ENA_W1S, (~0ULL));
244 nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_LO_ENA_W1S, (~0ULL));
245 nitrox_write_csr(ndev, NPS_PKT_SLC_ERR_TYPE_ENA_W1S, (~0uLL));
248 void nitrox_config_nps_unit(struct nitrox_device *ndev)
250 union nps_core_gbl_vfcfg core_gbl_vfcfg;
252 /* endian control information */
253 nitrox_write_csr(ndev, NPS_CORE_CONTROL, 1ULL);
255 /* disable ILK interface */
256 core_gbl_vfcfg.value = 0;
257 core_gbl_vfcfg.s.ilk_disable = 1;
258 core_gbl_vfcfg.s.cfg = PF_MODE;
259 nitrox_write_csr(ndev, NPS_CORE_GBL_VFCFG, core_gbl_vfcfg.value);
260 /* config input and solicit ports */
261 nitrox_config_pkt_input_rings(ndev);
262 nitrox_config_pkt_solicit_ports(ndev);
264 /* enable interrupts */
265 enable_nps_interrupts(ndev);
268 void nitrox_config_pom_unit(struct nitrox_device *ndev)
270 union pom_int_ena_w1s pom_int;
273 /* enable pom interrupts */
275 pom_int.s.illegal_dport = 1;
276 nitrox_write_csr(ndev, POM_INT_ENA_W1S, pom_int.value);
278 /* enable perf counters */
279 for (i = 0; i < ndev->hw.se_cores; i++)
280 nitrox_write_csr(ndev, POM_PERF_CTL, BIT_ULL(i));
284 * nitrox_config_rand_unit - enable N5 random number unit
287 void nitrox_config_rand_unit(struct nitrox_device *ndev)
289 union efl_rnm_ctl_status efl_rnm_ctl;
292 offset = EFL_RNM_CTL_STATUS;
293 efl_rnm_ctl.value = nitrox_read_csr(ndev, offset);
294 efl_rnm_ctl.s.ent_en = 1;
295 efl_rnm_ctl.s.rng_en = 1;
296 nitrox_write_csr(ndev, offset, efl_rnm_ctl.value);
299 void nitrox_config_efl_unit(struct nitrox_device *ndev)
303 for (i = 0; i < NR_CLUSTERS; i++) {
304 union efl_core_int_ena_w1s efl_core_int;
307 /* EFL core interrupts */
308 offset = EFL_CORE_INT_ENA_W1SX(i);
309 efl_core_int.value = 0;
310 efl_core_int.s.len_ovr = 1;
311 efl_core_int.s.d_left = 1;
312 efl_core_int.s.epci_decode_err = 1;
313 nitrox_write_csr(ndev, offset, efl_core_int.value);
315 offset = EFL_CORE_VF_ERR_INT0_ENA_W1SX(i);
316 nitrox_write_csr(ndev, offset, (~0ULL));
317 offset = EFL_CORE_VF_ERR_INT1_ENA_W1SX(i);
318 nitrox_write_csr(ndev, offset, (~0ULL));
322 void nitrox_config_bmi_unit(struct nitrox_device *ndev)
324 union bmi_ctl bmi_ctl;
325 union bmi_int_ena_w1s bmi_int_ena;
328 /* no threshold limits for PCIe */
330 bmi_ctl.value = nitrox_read_csr(ndev, offset);
331 bmi_ctl.s.max_pkt_len = 0xff;
332 bmi_ctl.s.nps_free_thrsh = 0xff;
333 bmi_ctl.s.nps_hdrq_thrsh = 0x7a;
334 nitrox_write_csr(ndev, offset, bmi_ctl.value);
336 /* enable interrupts */
337 offset = BMI_INT_ENA_W1S;
338 bmi_int_ena.value = 0;
339 bmi_int_ena.s.max_len_err_nps = 1;
340 bmi_int_ena.s.pkt_rcv_err_nps = 1;
341 bmi_int_ena.s.fpf_undrrn = 1;
342 nitrox_write_csr(ndev, offset, bmi_int_ena.value);
345 void nitrox_config_bmo_unit(struct nitrox_device *ndev)
347 union bmo_ctl2 bmo_ctl2;
350 /* no threshold limits for PCIe */
352 bmo_ctl2.value = nitrox_read_csr(ndev, offset);
353 bmo_ctl2.s.nps_slc_buf_thrsh = 0xff;
354 nitrox_write_csr(ndev, offset, bmo_ctl2.value);
357 void invalidate_lbc(struct nitrox_device *ndev)
359 union lbc_inval_ctl lbc_ctl;
360 union lbc_inval_status lbc_stat;
364 offset = LBC_INVAL_CTL;
365 lbc_ctl.value = nitrox_read_csr(ndev, offset);
366 lbc_ctl.s.cam_inval_start = 1;
367 nitrox_write_csr(ndev, offset, lbc_ctl.value);
369 offset = LBC_INVAL_STATUS;
372 lbc_stat.value = nitrox_read_csr(ndev, offset);
373 } while (!lbc_stat.s.done);
376 void nitrox_config_lbc_unit(struct nitrox_device *ndev)
378 union lbc_int_ena_w1s lbc_int_ena;
381 invalidate_lbc(ndev);
383 /* enable interrupts */
384 offset = LBC_INT_ENA_W1S;
385 lbc_int_ena.value = 0;
386 lbc_int_ena.s.dma_rd_err = 1;
387 lbc_int_ena.s.over_fetch_err = 1;
388 lbc_int_ena.s.cam_inval_abort = 1;
389 lbc_int_ena.s.cam_hard_err = 1;
390 nitrox_write_csr(ndev, offset, lbc_int_ena.value);
392 offset = LBC_PLM_VF1_64_INT_ENA_W1S;
393 nitrox_write_csr(ndev, offset, (~0ULL));
394 offset = LBC_PLM_VF65_128_INT_ENA_W1S;
395 nitrox_write_csr(ndev, offset, (~0ULL));
397 offset = LBC_ELM_VF1_64_INT_ENA_W1S;
398 nitrox_write_csr(ndev, offset, (~0ULL));
399 offset = LBC_ELM_VF65_128_INT_ENA_W1S;
400 nitrox_write_csr(ndev, offset, (~0ULL));