Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2022 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : : #include "roc_priv.h"
7 : :
8 : : #define TIME_SEC_IN_MS 1000
9 : :
10 : : static int
11 : 0 : roc_ml_reg_wait_to_clear(struct roc_ml *roc_ml, uint64_t offset, uint64_t mask)
12 : : {
13 : : uint64_t start_cycle;
14 : : uint64_t wait_cycles;
15 : : uint64_t reg_val;
16 : :
17 : 0 : wait_cycles = (ROC_ML_TIMEOUT_MS * plt_tsc_hz()) / TIME_SEC_IN_MS;
18 : : start_cycle = plt_tsc_cycles();
19 : : do {
20 : 0 : reg_val = roc_ml_reg_read64(roc_ml, offset);
21 : :
22 [ # # ]: 0 : if (!(reg_val & mask))
23 : : return 0;
24 [ # # ]: 0 : } while (plt_tsc_cycles() - start_cycle < wait_cycles);
25 : :
26 : : return -ETIME;
27 : : }
28 : :
29 : : uint64_t
30 : 0 : roc_ml_reg_read64(struct roc_ml *roc_ml, uint64_t offset)
31 : : {
32 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
33 : :
34 : 0 : return plt_read64(PLT_PTR_ADD(ml->ml_reg_addr, offset));
35 : : }
36 : :
37 : : void
38 : 0 : roc_ml_reg_write64(struct roc_ml *roc_ml, uint64_t val, uint64_t offset)
39 : : {
40 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
41 : :
42 : 0 : plt_write64(val, PLT_PTR_ADD(ml->ml_reg_addr, offset));
43 : 0 : }
44 : :
45 : : uint32_t
46 : 0 : roc_ml_reg_read32(struct roc_ml *roc_ml, uint64_t offset)
47 : : {
48 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
49 : :
50 : 0 : return plt_read32(PLT_PTR_ADD(ml->ml_reg_addr, offset));
51 : : }
52 : :
53 : : void
54 : 0 : roc_ml_reg_write32(struct roc_ml *roc_ml, uint32_t val, uint64_t offset)
55 : : {
56 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
57 : :
58 : 0 : plt_write32(val, PLT_PTR_ADD(ml->ml_reg_addr, offset));
59 : 0 : }
60 : :
61 : : void
62 : 0 : roc_ml_reg_save(struct roc_ml *roc_ml, uint64_t offset)
63 : : {
64 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
65 : :
66 [ # # ]: 0 : if (offset == ML_MLR_BASE) {
67 : 0 : ml->ml_mlr_base =
68 : 0 : FIELD_GET(ROC_ML_MLR_BASE_BASE, roc_ml_reg_read64(roc_ml, offset));
69 : 0 : ml->ml_mlr_base_saved = true;
70 : : }
71 : 0 : }
72 : :
73 : : void *
74 : 0 : roc_ml_addr_ap2mlip(struct roc_ml *roc_ml, void *addr)
75 : : {
76 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
77 : : uint64_t ml_mlr_base;
78 : :
79 [ # # ]: 0 : ml_mlr_base = (ml->ml_mlr_base_saved) ? ml->ml_mlr_base :
80 : 0 : FIELD_GET(ROC_ML_MLR_BASE_BASE,
81 : : roc_ml_reg_read64(roc_ml, ML_MLR_BASE));
82 : 0 : return PLT_PTR_ADD(addr, ML_AXI_START_ADDR - ml_mlr_base);
83 : : }
84 : :
85 : : void *
86 : 0 : roc_ml_addr_mlip2ap(struct roc_ml *roc_ml, void *addr)
87 : : {
88 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
89 : : uint64_t ml_mlr_base;
90 : :
91 [ # # ]: 0 : ml_mlr_base = (ml->ml_mlr_base_saved) ? ml->ml_mlr_base :
92 : 0 : FIELD_GET(ROC_ML_MLR_BASE_BASE,
93 : : roc_ml_reg_read64(roc_ml, ML_MLR_BASE));
94 : 0 : return PLT_PTR_ADD(addr, ml_mlr_base - ML_AXI_START_ADDR);
95 : : }
96 : :
97 : : uint64_t
98 [ # # ]: 0 : roc_ml_addr_pa_to_offset(struct roc_ml *roc_ml, uint64_t phys_addr)
99 : : {
100 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
101 : :
102 [ # # ]: 0 : if (roc_model_is_cn10ka())
103 : 0 : return phys_addr - ml->pci_dev->mem_resource[0].phys_addr;
104 : : else
105 : 0 : return phys_addr - ml->pci_dev->mem_resource[0].phys_addr - ML_MLAB_BLK_OFFSET;
106 : : }
107 : :
108 : : uint64_t
109 [ # # ]: 0 : roc_ml_addr_offset_to_pa(struct roc_ml *roc_ml, uint64_t offset)
110 : : {
111 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
112 : :
113 [ # # ]: 0 : if (roc_model_is_cn10ka())
114 : 0 : return ml->pci_dev->mem_resource[0].phys_addr + offset;
115 : : else
116 : 0 : return ml->pci_dev->mem_resource[0].phys_addr + ML_MLAB_BLK_OFFSET + offset;
117 : : }
118 : :
119 : : void
120 : 0 : roc_ml_scratch_write_job(struct roc_ml *roc_ml, void *work_ptr)
121 : : {
122 : : union ml_scratch_work_ptr_s reg_work_ptr;
123 : : union ml_scratch_fw_ctrl_s reg_fw_ctrl;
124 : :
125 : 0 : reg_work_ptr.u64 = 0;
126 : 0 : reg_work_ptr.s.work_ptr = PLT_U64_CAST(roc_ml_addr_ap2mlip(roc_ml, work_ptr));
127 : :
128 : : reg_fw_ctrl.u64 = 0;
129 : : reg_fw_ctrl.s.valid = 1;
130 : :
131 : 0 : roc_ml_reg_write64(roc_ml, reg_work_ptr.u64, ML_SCRATCH_WORK_PTR);
132 : 0 : roc_ml_reg_write64(roc_ml, reg_fw_ctrl.u64, ML_SCRATCH_FW_CTRL);
133 : 0 : }
134 : :
135 : : bool
136 : 0 : roc_ml_scratch_is_valid_bit_set(struct roc_ml *roc_ml)
137 : : {
138 : : union ml_scratch_fw_ctrl_s reg_fw_ctrl;
139 : :
140 : 0 : reg_fw_ctrl.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_FW_CTRL);
141 : :
142 [ # # ]: 0 : if (reg_fw_ctrl.s.valid == 1)
143 : 0 : return true;
144 : :
145 : : return false;
146 : : }
147 : :
148 : : bool
149 : 0 : roc_ml_scratch_is_done_bit_set(struct roc_ml *roc_ml)
150 : : {
151 : : union ml_scratch_fw_ctrl_s reg_fw_ctrl;
152 : :
153 : 0 : reg_fw_ctrl.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_FW_CTRL);
154 : :
155 [ # # ]: 0 : if (reg_fw_ctrl.s.done == 1)
156 : 0 : return true;
157 : :
158 : : return false;
159 : : }
160 : :
161 : : bool
162 : 0 : roc_ml_scratch_enqueue(struct roc_ml *roc_ml, void *work_ptr)
163 : : {
164 : : union ml_scratch_work_ptr_s reg_work_ptr;
165 : : union ml_scratch_fw_ctrl_s reg_fw_ctrl;
166 : : bool ret = false;
167 : :
168 : 0 : reg_work_ptr.u64 = 0;
169 : 0 : reg_work_ptr.s.work_ptr = PLT_U64_CAST(roc_ml_addr_ap2mlip(roc_ml, work_ptr));
170 : :
171 : 0 : reg_fw_ctrl.u64 = 0;
172 : 0 : reg_fw_ctrl.s.valid = 1;
173 : :
174 [ # # ]: 0 : if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
175 : 0 : bool valid = roc_ml_scratch_is_valid_bit_set(roc_ml);
176 : 0 : bool done = roc_ml_scratch_is_done_bit_set(roc_ml);
177 : :
178 [ # # ]: 0 : if (valid == done) {
179 : 0 : roc_ml_clk_force_on(roc_ml);
180 : 0 : roc_ml_dma_stall_off(roc_ml);
181 : :
182 : 0 : roc_ml_reg_write64(roc_ml, reg_work_ptr.u64, ML_SCRATCH_WORK_PTR);
183 : 0 : roc_ml_reg_write64(roc_ml, reg_fw_ctrl.u64, ML_SCRATCH_FW_CTRL);
184 : :
185 : : ret = true;
186 : : }
187 : : plt_spinlock_unlock(&roc_ml->sp_spinlock);
188 : : }
189 : :
190 : 0 : return ret;
191 : : }
192 : :
193 : : bool
194 : 0 : roc_ml_scratch_dequeue(struct roc_ml *roc_ml, void *work_ptr)
195 : : {
196 : : union ml_scratch_work_ptr_s reg_work_ptr;
197 : : bool ret = false;
198 : :
199 [ # # ]: 0 : if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
200 : 0 : bool valid = roc_ml_scratch_is_valid_bit_set(roc_ml);
201 : 0 : bool done = roc_ml_scratch_is_done_bit_set(roc_ml);
202 : :
203 [ # # ]: 0 : if (valid && done) {
204 : 0 : reg_work_ptr.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_WORK_PTR);
205 [ # # ]: 0 : if (work_ptr ==
206 : 0 : roc_ml_addr_mlip2ap(roc_ml, PLT_PTR_CAST(reg_work_ptr.u64))) {
207 : 0 : roc_ml_dma_stall_on(roc_ml);
208 : 0 : roc_ml_clk_force_off(roc_ml);
209 : :
210 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
211 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_FW_CTRL);
212 : : ret = true;
213 : : }
214 : : }
215 : : plt_spinlock_unlock(&roc_ml->sp_spinlock);
216 : : }
217 : :
218 : 0 : return ret;
219 : : }
220 : :
221 : : void
222 : 0 : roc_ml_scratch_queue_reset(struct roc_ml *roc_ml)
223 : : {
224 [ # # ]: 0 : if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
225 : 0 : roc_ml_dma_stall_on(roc_ml);
226 : 0 : roc_ml_clk_force_off(roc_ml);
227 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
228 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_FW_CTRL);
229 : : plt_spinlock_unlock(&roc_ml->sp_spinlock);
230 : : }
231 : 0 : }
232 : :
233 : : bool
234 : 0 : roc_ml_jcmdq_enqueue_lf(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd)
235 : : {
236 : : bool ret = false;
237 : :
238 [ # # ]: 0 : if (FIELD_GET(ROC_ML_JCMDQ_STATUS_AVAIL_COUNT,
239 : : roc_ml_reg_read64(roc_ml, ML_JCMDQ_STATUS)) != 0) {
240 : 0 : roc_ml_reg_write64(roc_ml, job_cmd->w0.u64, ML_JCMDQ_IN(0));
241 : 0 : roc_ml_reg_write64(roc_ml, job_cmd->w1.u64, ML_JCMDQ_IN(1));
242 : : ret = true;
243 : : }
244 : :
245 : 0 : return ret;
246 : : }
247 : :
248 : : bool
249 : 0 : roc_ml_jcmdq_enqueue_sl(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd)
250 : : {
251 : : bool ret = false;
252 : :
253 [ # # ]: 0 : if (plt_spinlock_trylock(&roc_ml->fp_spinlock) != 0) {
254 [ # # ]: 0 : if (FIELD_GET(ROC_ML_JCMDQ_STATUS_AVAIL_COUNT,
255 : : roc_ml_reg_read64(roc_ml, ML_JCMDQ_STATUS)) != 0) {
256 : 0 : roc_ml_reg_write64(roc_ml, job_cmd->w0.u64, ML_JCMDQ_IN(0));
257 : 0 : roc_ml_reg_write64(roc_ml, job_cmd->w1.u64, ML_JCMDQ_IN(1));
258 : : ret = true;
259 : : }
260 : : plt_spinlock_unlock(&roc_ml->fp_spinlock);
261 : : }
262 : :
263 : 0 : return ret;
264 : : }
265 : :
266 : : void
267 : 0 : roc_ml_clk_force_on(struct roc_ml *roc_ml)
268 : : {
269 : : uint64_t reg_val = 0;
270 : :
271 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
272 : 0 : reg_val |= ROC_ML_CFG_MLIP_CLK_FORCE;
273 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
274 : 0 : }
275 : :
276 : : void
277 : 0 : roc_ml_clk_force_off(struct roc_ml *roc_ml)
278 : : {
279 : : uint64_t reg_val = 0;
280 : :
281 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
282 : :
283 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
284 : 0 : reg_val &= ~ROC_ML_CFG_MLIP_CLK_FORCE;
285 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
286 : 0 : }
287 : :
288 : : void
289 : 0 : roc_ml_dma_stall_on(struct roc_ml *roc_ml)
290 : : {
291 : : uint64_t reg_val = 0;
292 : :
293 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_JOB_MGR_CTRL);
294 : 0 : reg_val |= ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;
295 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_JOB_MGR_CTRL);
296 : 0 : }
297 : :
298 : : void
299 : 0 : roc_ml_dma_stall_off(struct roc_ml *roc_ml)
300 : : {
301 : : uint64_t reg_val = 0;
302 : :
303 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_JOB_MGR_CTRL);
304 : 0 : reg_val &= ~ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;
305 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_JOB_MGR_CTRL);
306 : 0 : }
307 : :
308 : : bool
309 : 0 : roc_ml_mlip_is_enabled(struct roc_ml *roc_ml)
310 : : {
311 : : uint64_t reg_val;
312 : :
313 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
314 : :
315 [ # # ]: 0 : if ((reg_val & ROC_ML_CFG_MLIP_ENA) != 0)
316 : 0 : return true;
317 : :
318 : : return false;
319 : : }
320 : :
321 : : int
322 : 0 : roc_ml_mlip_reset(struct roc_ml *roc_ml, bool force)
323 : : {
324 : : uint64_t reg_val;
325 : :
326 : : /* Force reset */
327 [ # # ]: 0 : if (force) {
328 : : /* Set ML(0)_CFG[ENA] = 0. */
329 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
330 : 0 : reg_val &= ~ROC_ML_CFG_ENA;
331 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
332 : :
333 : : /* Set ML(0)_CFG[MLIP_ENA] = 0. */
334 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
335 : 0 : reg_val &= ~ROC_ML_CFG_MLIP_ENA;
336 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
337 : :
338 : : /* Clear ML_MLR_BASE */
339 : 0 : roc_ml_reg_write64(roc_ml, 0, ML_MLR_BASE);
340 : : }
341 : :
342 [ # # ]: 0 : if (roc_model_is_cn10ka()) {
343 : : /* Wait for all active jobs to finish.
344 : : * ML_CFG[ENA] : When set, MLW will accept job commands. This
345 : : * bit can be cleared at any time. If [BUSY] is set, software
346 : : * must wait until [BUSY] == 0 before setting this bit.
347 : : */
348 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_CFG, ROC_ML_CFG_BUSY);
349 : :
350 : : /* (1) Set ML(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] = 1 to instruct
351 : : * the AXI bridge not to accept any new transactions from MLIP.
352 : : */
353 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
354 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
355 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
356 : :
357 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
358 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
359 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
360 : :
361 : : /* (2) Wait until ML(0)_AXI_BRIDGE_CTRL(0..1)[BUSY] = 0 which
362 : : * indicates that there is no outstanding transactions on
363 : : * AXI-NCB paths.
364 : : */
365 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(0),
366 : : ROC_ML_AXI_BRIDGE_CTRL_BUSY);
367 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(1),
368 : : ROC_ML_AXI_BRIDGE_CTRL_BUSY);
369 : :
370 : : /* (3) Wait until ML(0)_JOB_MGR_CTRL[BUSY] = 0 which indicates
371 : : * that there are no pending jobs in the MLW's job manager.
372 : : */
373 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_JOB_MGR_CTRL, ROC_ML_JOB_MGR_CTRL_BUSY);
374 : :
375 : : /* (4) Set ML(0)_CFG[ENA] = 0. */
376 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
377 : 0 : reg_val &= ~ROC_ML_CFG_ENA;
378 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
379 : :
380 : : /* (5) Set ML(0)_CFG[MLIP_ENA] = 0. */
381 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
382 : 0 : reg_val &= ~ROC_ML_CFG_MLIP_ENA;
383 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
384 : :
385 : : /* (6) Set ML(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] = 0.*/
386 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
387 : 0 : reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
388 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
389 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
390 : : }
391 : :
392 [ # # ]: 0 : if (roc_model_is_cnf10kb()) {
393 : : /* (1) Clear MLAB(0)_CFG[ENA]. Any new jobs will bypass the job
394 : : * execution stages and their completions will be returned to
395 : : * PSM.
396 : : */
397 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
398 : 0 : reg_val &= ~ROC_ML_CFG_ENA;
399 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
400 : :
401 : : /* (2) Quiesce the ACC and DMA AXI interfaces: For each of the
402 : : * two MLAB(0)_AXI_BRIDGE_CTRL(0..1) registers:
403 : : *
404 : : * (a) Set MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] to block new AXI
405 : : * commands from MLIP.
406 : : *
407 : : * (b) Poll MLAB(0)_AXI_BRIDGE_CTRL(0..1)[BUSY] == 0.
408 : : */
409 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
410 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
411 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
412 : :
413 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(0),
414 : : ROC_ML_AXI_BRIDGE_CTRL_BUSY);
415 : :
416 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
417 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
418 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
419 : :
420 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(1),
421 : : ROC_ML_AXI_BRIDGE_CTRL_BUSY);
422 : :
423 : : /* (3) Clear MLAB(0)_CFG[MLIP_ENA] to reset MLIP.
424 : : */
425 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
426 : 0 : reg_val &= ~ROC_ML_CFG_MLIP_ENA;
427 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
428 : :
429 : 0 : cnf10kb_mlip_reset_stage_4a:
430 : : /* (4) Flush any outstanding jobs in MLAB's job execution
431 : : * stages:
432 : : *
433 : : * (a) Wait for completion stage to clear:
434 : : * - Poll MLAB(0)_STG(0..2)_STATUS[VALID] == 0.
435 : : */
436 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(0), ROC_ML_STG_STATUS_VALID);
437 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(1), ROC_ML_STG_STATUS_VALID);
438 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(2), ROC_ML_STG_STATUS_VALID);
439 : :
440 : 0 : cnf10kb_mlip_reset_stage_4b:
441 : : /* (4b) Clear job run stage: Poll
442 : : * MLAB(0)_STG_CONTROL[RUN_TO_COMP] == 0.
443 : : */
444 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL, ROC_ML_STG_CONTROL_RUN_TO_COMP);
445 : :
446 : : /* (4b) Clear job run stage: If MLAB(0)_STG(1)_STATUS[VALID] ==
447 : : * 1:
448 : : * - Set MLAB(0)_STG_CONTROL[RUN_TO_COMP].
449 : : * - Poll MLAB(0)_STG_CONTROL[RUN_TO_COMP] == 0.
450 : : * - Repeat step (a) to clear job completion stage.
451 : : */
452 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(1));
453 [ # # ]: 0 : if (reg_val & ROC_ML_STG_STATUS_VALID) {
454 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_STG_CONTROL);
455 : 0 : reg_val |= ROC_ML_STG_CONTROL_RUN_TO_COMP;
456 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_STG_CONTROL);
457 : :
458 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL,
459 : : ROC_ML_STG_CONTROL_RUN_TO_COMP);
460 : :
461 : 0 : goto cnf10kb_mlip_reset_stage_4a;
462 : : }
463 : :
464 : : /* (4c) Clear job fetch stage: Poll
465 : : * MLAB(0)_STG_CONTROL[FETCH_TO_RUN] == 0.
466 : : */
467 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL, ROC_ML_STG_CONTROL_FETCH_TO_RUN);
468 : :
469 : : /* (4c) Clear job fetch stage: If
470 : : * MLAB(0)_STG(0..2)_STATUS[VALID] == 1:
471 : : * - Set MLAB(0)_STG_CONTROL[FETCH_TO_RUN].
472 : : * - Poll MLAB(0)_STG_CONTROL[FETCH_TO_RUN] == 0.
473 : : * - Repeat step (b) to clear job run and completion stages.
474 : : */
475 : 0 : reg_val = (roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(0)) |
476 : 0 : roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(1)) |
477 : 0 : roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(2)));
478 : :
479 [ # # ]: 0 : if (reg_val & ROC_ML_STG_STATUS_VALID) {
480 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_STG_CONTROL);
481 : 0 : reg_val |= ROC_ML_STG_CONTROL_RUN_TO_COMP;
482 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_STG_CONTROL);
483 : :
484 : 0 : roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL,
485 : : ROC_ML_STG_CONTROL_RUN_TO_COMP);
486 : :
487 : 0 : goto cnf10kb_mlip_reset_stage_4b;
488 : : }
489 : :
490 : : /* (5) Reset the ACC and DMA AXI interfaces: For each of the two
491 : : * MLAB(0)_AXI_BRIDGE_CTRL(0..1) registers:
492 : : *
493 : : * (5a) Set and then clear
494 : : * MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FLUSH_WRITE_DATA].
495 : : *
496 : : * (5b) Clear MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FENCE].
497 : : */
498 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
499 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
500 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
501 : :
502 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
503 : 0 : reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
504 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
505 : :
506 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
507 : 0 : reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
508 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
509 : :
510 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
511 : 0 : reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
512 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
513 : :
514 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
515 : 0 : reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
516 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
517 : :
518 : 0 : reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
519 : 0 : reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
520 : 0 : roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
521 : : }
522 : :
523 : 0 : return 0;
524 : : }
525 : :
526 : : int
527 : 0 : roc_ml_dev_init(struct roc_ml *roc_ml)
528 : : {
529 : : struct plt_pci_device *pci_dev;
530 : : struct dev *dev;
531 : : struct ml *ml;
532 : :
533 [ # # # # ]: 0 : if (roc_ml == NULL || roc_ml->pci_dev == NULL)
534 : : return -EINVAL;
535 : :
536 : : PLT_STATIC_ASSERT(sizeof(struct ml) <= ROC_ML_MEM_SZ);
537 : :
538 : : ml = roc_ml_to_ml_priv(roc_ml);
539 : : memset(ml, 0, sizeof(*ml));
540 : : pci_dev = roc_ml->pci_dev;
541 : : dev = &ml->dev;
542 : :
543 : 0 : ml->pci_dev = pci_dev;
544 : 0 : dev->roc_ml = roc_ml;
545 : :
546 : 0 : ml->ml_reg_addr = ml->pci_dev->mem_resource[0].addr;
547 : 0 : ml->ml_mlr_base = 0;
548 : 0 : ml->ml_mlr_base_saved = false;
549 : :
550 : 0 : plt_ml_dbg("ML: PCI Physical Address : 0x%016lx", ml->pci_dev->mem_resource[0].phys_addr);
551 : 0 : plt_ml_dbg("ML: PCI Virtual Address : 0x%016lx",
552 : : PLT_U64_CAST(ml->pci_dev->mem_resource[0].addr));
553 : :
554 : : plt_spinlock_init(&roc_ml->sp_spinlock);
555 : : plt_spinlock_init(&roc_ml->fp_spinlock);
556 : :
557 : 0 : return 0;
558 : : }
559 : :
560 : : int
561 : 0 : roc_ml_dev_fini(struct roc_ml *roc_ml)
562 : : {
563 : : struct ml *ml = roc_ml_to_ml_priv(roc_ml);
564 : :
565 : : if (ml == NULL)
566 : : return -EINVAL;
567 : :
568 : : return 0;
569 : : }
570 : :
571 : : int
572 : 0 : roc_ml_blk_init(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml)
573 : : {
574 : : struct dev *dev;
575 : : struct ml *ml;
576 : :
577 [ # # ]: 0 : if ((roc_ml == NULL) || (roc_bphy == NULL))
578 : : return -EINVAL;
579 : :
580 : : PLT_STATIC_ASSERT(sizeof(struct ml) <= ROC_ML_MEM_SZ);
581 : :
582 : : ml = roc_ml_to_ml_priv(roc_ml);
583 : : memset(ml, 0, sizeof(*ml));
584 : :
585 : : dev = &ml->dev;
586 : :
587 : 0 : ml->pci_dev = roc_bphy->pci_dev;
588 : 0 : dev->roc_ml = roc_ml;
589 : :
590 : 0 : plt_ml_dbg(
591 : : "MLAB: Physical Address : 0x%016lx",
592 : : PLT_PTR_ADD_U64_CAST(ml->pci_dev->mem_resource[0].phys_addr, ML_MLAB_BLK_OFFSET));
593 : 0 : plt_ml_dbg("MLAB: Virtual Address : 0x%016lx",
594 : : PLT_PTR_ADD_U64_CAST(ml->pci_dev->mem_resource[0].addr, ML_MLAB_BLK_OFFSET));
595 : :
596 : 0 : ml->ml_reg_addr = PLT_PTR_ADD(ml->pci_dev->mem_resource[0].addr, ML_MLAB_BLK_OFFSET);
597 : 0 : ml->ml_mlr_base = 0;
598 : 0 : ml->ml_mlr_base_saved = false;
599 : :
600 : : plt_spinlock_init(&roc_ml->sp_spinlock);
601 : : plt_spinlock_init(&roc_ml->fp_spinlock);
602 : :
603 : 0 : return 0;
604 : : }
605 : :
606 : : int
607 : 0 : roc_ml_blk_fini(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml)
608 : : {
609 : : struct ml *ml;
610 : :
611 [ # # ]: 0 : if ((roc_ml == NULL) || (roc_bphy == NULL))
612 : 0 : return -EINVAL;
613 : :
614 : : ml = roc_ml_to_ml_priv(roc_ml);
615 : :
616 : : if (ml == NULL)
617 : : return -EINVAL;
618 : :
619 : : return 0;
620 : : }
621 : :
622 : : uint16_t
623 : 0 : roc_ml_sso_pf_func_get(void)
624 : : {
625 : 0 : return idev_sso_pffunc_get();
626 : : }
|