1 /* Copyright 2013-2019 IBM Corp.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 * implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <skiboot.h>
17 #include <io.h>
18 #include <timebase.h>
19 #include <pci.h>
20 #include <pci-virt.h>
21 #include <interrupts.h>
22 #include <npu-regs.h>
23 #include <npu.h>
24 #include <xscom.h>
25
26 typedef uint32_t (*step)(struct npu_dev *);
27
28 struct procedure {
29 const char *name;
30 step steps[];
31 };
32
33 #define DEFINE_PROCEDURE(NAME, STEPS...) \
34 static struct procedure procedure_##NAME = \
35 {.name = #NAME, .steps = {NAME, ##STEPS}}
36
37 #define PROCEDURE_INPROGRESS (1 << 31)
38 #define PROCEDURE_COMPLETE (1 << 30)
39 #define PROCEDURE_NEXT (1 << 29)
40 #define PROCEDURE_FAILED 2
41 #define PROCEDURE_ABORTED 3
42 #define PROCEDURE_UNSUPPORTED 4
43
44 /* Mask defining which status bits we want to expose */
45 #define PROCEDURE_STATUS_MASK 0xc000000f
46
47 /* Accesors for PHY registers. These can be done either via MMIO or SCOM. */
48 static bool pl_use_scom = 1;
phy_write(struct npu_dev * npu_dev,uint64_t addr,uint32_t val)49 static void phy_write(struct npu_dev *npu_dev, uint64_t addr, uint32_t val)
50 {
51 if (pl_use_scom)
52 xscom_write(npu_dev->npu->chip_id, npu_dev->pl_xscom_base | addr, val);
53 else
54 out_be16((void *) npu_dev->pl_base + PL_MMIO_ADDR(addr), val);
55 }
56
phy_read(struct npu_dev * npu_dev,uint64_t addr)57 static uint16_t phy_read(struct npu_dev *npu_dev, uint64_t addr)
58 {
59 uint64_t val;
60
61 if (pl_use_scom)
62 xscom_read(npu_dev->npu->chip_id, npu_dev->pl_xscom_base + addr, &val);
63 else
64 val = in_be16((void *) npu_dev->pl_base + PL_MMIO_ADDR(addr));
65
66 return val & 0xffff;
67 }
68
69 /* The DL registers can be accessed indirectly via the NTL */
dl_write(struct npu_dev * npu_dev,uint32_t addr,uint32_t val)70 static void dl_write(struct npu_dev *npu_dev, uint32_t addr, uint32_t val)
71 {
72 xscom_write(npu_dev->npu->chip_id,
73 npu_dev->xscom + NX_DL_REG_ADDR, addr);
74 xscom_write(npu_dev->npu->chip_id,
75 npu_dev->xscom + NX_DL_REG_DATA, val);
76 }
77
dl_read(struct npu_dev * npu_dev,uint32_t addr)78 static uint64_t __unused dl_read(struct npu_dev *npu_dev, uint32_t addr)
79 {
80 uint64_t val;
81
82 xscom_write(npu_dev->npu->chip_id,
83 npu_dev->xscom + NX_DL_REG_ADDR, addr);
84 xscom_read(npu_dev->npu->chip_id,
85 npu_dev->xscom + NX_DL_REG_DATA, &val);
86 return val;
87 }
88
89 /* Our hardware bits are backwards here. The lane vectors are 16-bit
90 * values represented in IBM bit ordering. This means lane 0 is
91 * represented by bit 15 in most of the registers. Internally we keep
92 * this sane (ie. npu_dev->lane_mask[0] == lane 0) as we need sane
93 * numbering for set_lane_reg() anyway. */
phy_lane_mask(struct npu_dev * npu_dev)94 static uint32_t phy_lane_mask(struct npu_dev *npu_dev)
95 {
96 /* We only train 8 lanes at a time so we don't do a full
97 * bit-swap */
98 assert(npu_dev->lane_mask == 0xff00 || npu_dev->lane_mask == 0xff);
99
100 return ~npu_dev->lane_mask & 0xffff;
101 }
102
set_lane_reg(struct npu_dev * npu_dev,uint64_t base_reg,uint64_t data,uint64_t mask)103 static void set_lane_reg(struct npu_dev *npu_dev, uint64_t base_reg,
104 uint64_t data, uint64_t mask)
105 {
106 uint64_t val, i;
107 uint32_t lane_mask = npu_dev->lane_mask;
108
109 for (i = 0; i <= 23; i++) {
110 if (lane_mask & (1ul << i)) {
111 uint64_t tx_rxcal_reg = base_reg + (i << 32);
112 val = phy_read(npu_dev, tx_rxcal_reg);
113 val = (val & ~mask) | data;
114 phy_write(npu_dev, tx_rxcal_reg, val);
115 }
116 }
117 }
118
stop(struct npu_dev * npu_dev __unused)119 static uint32_t stop(struct npu_dev *npu_dev __unused)
120 {
121 return PROCEDURE_COMPLETE | PROCEDURE_ABORTED;
122 }
123 DEFINE_PROCEDURE(stop);
124
nop(struct npu_dev * npu_dev __unused)125 static uint32_t nop(struct npu_dev *npu_dev __unused)
126 {
127 return PROCEDURE_COMPLETE;
128 }
129 DEFINE_PROCEDURE(nop);
130
131 /* Procedure 1.2.1 (RESET_NPU_DL) from opt_programmerguide.odt. Also
132 * incorporates AT reset. */
reset_npu_dl(struct npu_dev * npu_dev)133 static uint32_t reset_npu_dl(struct npu_dev *npu_dev)
134 {
135 uint64_t val;
136
137 /* Assert NPU reset */
138 xscom_read(npu_dev->npu->chip_id, npu_dev->xscom + NX_NTL_CONTROL, &val);
139 val |= NTL_CONTROL_RESET;
140 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_NTL_CONTROL, val);
141
142 /* Put the Nvidia logic in reset */
143 dl_write(npu_dev, NDL_CONTROL, 0xe8000000);
144
145 /* Release Nvidia logic from reset */
146 dl_write(npu_dev, NDL_CONTROL, 0);
147
148 /* Release NPU from reset */
149 val &= ~NTL_CONTROL_RESET;
150 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_NTL_CONTROL, val);
151
152 /* Setup up TL credits */
153 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_TL_CMD_CR, PPC_BIT(0));
154 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_TL_CMD_D_CR, PPC_BIT(0));
155 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_TL_RSP_CR, PPC_BIT(15));
156 xscom_write(npu_dev->npu->chip_id, npu_dev->xscom + NX_TL_RSP_D_CR, PPC_BIT(15));
157
158 /* Reset error registers. TODO: are there more we should clear here? */
159 npu_ioda_sel(npu_dev->npu, NPU_IODA_TBL_PESTB, 0, true);
160 for (val = 0; val < NPU_NUM_OF_PES; val++)
161 out_be64(npu_dev->npu->at_regs + NPU_IODA_DATA0, 0);
162
163 return PROCEDURE_COMPLETE;
164 }
165 DEFINE_PROCEDURE(reset_npu_dl);
166
167 /* Procedures 1.2.3 (reset_lanes) & 1.2.4
168 * (io_register_write_reset_values) */
phy_reset(struct npu_dev * npu_dev)169 static uint32_t phy_reset(struct npu_dev *npu_dev)
170 {
171 uint16_t val;
172
173 /* Lower run_lane inputs for lanes to be reset */
174 val = phy_read(npu_dev, RX_RUN_LANE_VEC_0_15);
175 val &= ~phy_lane_mask(npu_dev);
176 phy_write(npu_dev, RX_RUN_LANE_VEC_0_15, val);
177
178 return PROCEDURE_NEXT;
179 }
180
phy_reset_wait(struct npu_dev * npu_dev)181 static uint32_t phy_reset_wait(struct npu_dev *npu_dev)
182 {
183 uint16_t val;
184
185 /* Wait for lane busy outputs to go to zero for lanes to be
186 * reset */
187 val = phy_read(npu_dev, RX_LANE_BUSY_VEC_0_15);
188 if (val & phy_lane_mask(npu_dev))
189 return PROCEDURE_INPROGRESS;
190
191 return PROCEDURE_NEXT;
192 }
193
phy_reset_complete(struct npu_dev * npu_dev)194 static uint32_t phy_reset_complete(struct npu_dev *npu_dev)
195 {
196 uint16_t val;
197 uint32_t lane_mask = phy_lane_mask(npu_dev);
198
199 /* Set ioreset_vec for the desired lanes bit positions */
200 val = phy_read(npu_dev, RX_IORESET_VEC_0_15);
201 phy_write(npu_dev, RX_IORESET_VEC_0_15, val | lane_mask);
202
203 val = phy_read(npu_dev, TX_IORESET_VEC_0_15);
204 phy_write(npu_dev, TX_IORESET_VEC_0_15, val | lane_mask);
205
206 /* Clear ioreset_vec */
207 val = phy_read(npu_dev, RX_IORESET_VEC_0_15);
208 phy_write(npu_dev, RX_IORESET_VEC_0_15, val & ~lane_mask);
209
210 val = phy_read(npu_dev, TX_IORESET_VEC_0_15);
211 phy_write(npu_dev, TX_IORESET_VEC_0_15, val & ~lane_mask);
212
213 /* Reset RX phase rotators */
214 set_lane_reg(npu_dev, RX_PR_CNTL_PL, RX_PR_RESET, RX_PR_RESET);
215 set_lane_reg(npu_dev, RX_PR_CNTL_PL, 0, RX_PR_RESET);
216
217 /* Restore registers from scominit that may have changed */
218 set_lane_reg(npu_dev, RX_PR_MODE, 0x8, RX_PR_PHASE_STEP);
219 set_lane_reg(npu_dev, RX_A_DAC_CNTL,
220 0x7 << MASK_TO_LSH(RX_PR_IQ_RES_SEL),
221 RX_PR_IQ_RES_SEL);
222 set_lane_reg(npu_dev, TX_MODE1_PL, 0, TX_LANE_PDWN);
223 set_lane_reg(npu_dev, RX_BANK_CONTROLS, 0, RX_LANE_ANA_PDWN);
224 set_lane_reg(npu_dev, RX_MODE, 0, RX_LANE_DIG_PDWN);
225
226 return PROCEDURE_COMPLETE;
227 }
228 DEFINE_PROCEDURE(phy_reset, phy_reset_wait, phy_reset_complete);
229
230 /* Round a fixed decimal number. Frac is the number of fractional
231 * bits */
round(uint32_t val,int frac)232 static uint32_t round(uint32_t val, int frac)
233 {
234 if (val >> (frac - 1) & 0x1)
235 return (val >> frac) + 1;
236 else
237 return val >> frac;
238 }
239
240 #define ZCAL_MIN (10 << 3)
241 #define ZCAL_MAX (40 << 3)
242 #define ZCAL_K0 0x0
243 #define ZCAL_M 128
244 /* TODO: add a test case for the following values:
245
246 Initial values:
247 zcal_n = 0xda;
248 zcal_p = 0xc7;
249
250 Results:
251 pre_p = 0x0
252 pre_n = 0x0
253 margin_p = 0x0
254 margin_n = 0x0
255 total_en_p = 0x32
256 total_en_n = 0x37
257 */
258
phy_tx_zcal(struct npu_dev * npu_dev)259 static uint32_t phy_tx_zcal(struct npu_dev *npu_dev)
260 {
261 uint64_t val;
262
263 if (npu_dev->index < 2 && npu_dev->npu->tx_zcal_complete[0])
264 return PROCEDURE_COMPLETE;
265
266 if (npu_dev->index >= 2 && npu_dev->npu->tx_zcal_complete[1])
267 return PROCEDURE_COMPLETE;
268
269 /* Start calibration */
270 val = phy_read(npu_dev, TX_IMPCAL_SWO1_PB);
271 val &= TX_ZCAL_SWO_EN;
272 phy_write(npu_dev, TX_IMPCAL_SWO1_PB, val);
273 phy_write(npu_dev, TX_IMPCAL_SWO2_PB, 0x50 << 2);
274 val = phy_read(npu_dev, TX_IMPCAL_PB);
275 val |= TX_ZCAL_REQ;
276 phy_write(npu_dev, TX_IMPCAL_PB, val);
277
278 return PROCEDURE_NEXT;
279 }
280
phy_tx_zcal_wait(struct npu_dev * npu_dev)281 static uint32_t phy_tx_zcal_wait(struct npu_dev *npu_dev)
282 {
283 uint64_t val;
284
285 val = phy_read(npu_dev, TX_IMPCAL_PB);
286 if (!(val & TX_ZCAL_DONE))
287 return PROCEDURE_INPROGRESS;
288
289 if (val & TX_ZCAL_ERROR)
290 return PROCEDURE_COMPLETE | PROCEDURE_FAILED;
291
292 return PROCEDURE_NEXT;
293 }
294
phy_tx_zcal_calculate(struct npu_dev * npu_dev)295 static uint32_t phy_tx_zcal_calculate(struct npu_dev *npu_dev)
296 {
297 uint64_t val;
298 uint64_t zcal_n;
299 uint64_t zcal_p;
300 uint64_t margin_n;
301 uint64_t margin_p;
302 uint64_t pre_n;
303 uint64_t pre_p;
304 uint64_t total_en_n;
305 uint64_t total_en_p;
306
307 val = phy_read(npu_dev, TX_IMPCAL_NVAL_PB);
308 zcal_n = GETFIELD(TX_ZCAL_N, val);
309 val = phy_read(npu_dev, TX_IMPCAL_PVAL_PB);
310 zcal_p = GETFIELD(TX_ZCAL_P, val);
311
312 if ((zcal_n < ZCAL_MIN) || (zcal_n > ZCAL_MAX) ||
313 (zcal_p < ZCAL_MIN) || (zcal_p > ZCAL_MAX))
314 return PROCEDURE_COMPLETE | PROCEDURE_FAILED;
315
316 margin_n = (0x80 - ZCAL_M) * zcal_n / 2;
317 margin_p = (0x80 - ZCAL_M) * zcal_p / 2;
318 pre_n = (((0x80 * zcal_n) - (2 * margin_n)) * ZCAL_K0) / 0x80;
319 pre_p = (((0x80 * zcal_p) - (2 * margin_p)) * ZCAL_K0) / 0x80;
320
321 total_en_n = 0x80 * zcal_n - (2 * margin_n) - (pre_n & 1023);
322 total_en_p = 0x80 * zcal_p - (2 * margin_p) - (pre_p & 1023);
323
324 pre_p = round(pre_p, 9);
325 pre_n = round(pre_n, 9);
326 margin_p = round(margin_p, 9);
327 margin_n = round(margin_n, 9);
328 total_en_p = round(total_en_p, 9);
329 total_en_n = round(total_en_n, 9);
330
331 val = SETFIELD(TX_FFE_TOTAL_ENABLE_N_ENC, 0, total_en_n);
332 val = SETFIELD(TX_FFE_TOTAL_ENABLE_P_ENC, val, total_en_p);
333 phy_write(npu_dev, TX_FFE_TOTAL_2RSTEP_EN, val);
334
335 val = SETFIELD(TX_FFE_PRE_N_SEL_ENC, 0, pre_n);
336 val = SETFIELD(TX_FFE_PRE_P_SEL_ENC, val, pre_p);
337 phy_write(npu_dev, TX_FFE_PRE_2RSTEP_SEL, val);
338
339 val = SETFIELD(TX_FFE_MARGIN_PD_N_SEL_ENC, 0, margin_n);
340 val = SETFIELD(TX_FFE_MARGIN_PU_P_SEL_ENC, val, margin_p);
341 phy_write(npu_dev, TX_FFE_MARGIN_2RSTEP_SEL, val);
342
343 if (npu_dev->index < 2)
344 npu_dev->npu->tx_zcal_complete[0] = true;
345 else
346 npu_dev->npu->tx_zcal_complete[1] = true;
347
348 return PROCEDURE_COMPLETE;
349 }
350 DEFINE_PROCEDURE(phy_tx_zcal, phy_tx_zcal_wait, phy_tx_zcal_calculate);
351
phy_enable_tx_rxcal(struct npu_dev * npu_dev)352 static uint32_t phy_enable_tx_rxcal(struct npu_dev *npu_dev)
353 {
354 /* Turn common mode on */
355 set_lane_reg(npu_dev, TX_MODE2_PL, TX_RXCAL, TX_RXCAL);
356
357 return PROCEDURE_COMPLETE;
358 }
359 DEFINE_PROCEDURE(phy_enable_tx_rxcal);
360
phy_disable_tx_rxcal(struct npu_dev * npu_dev)361 static uint32_t phy_disable_tx_rxcal(struct npu_dev *npu_dev)
362 {
363 /* Turn common mode off */
364 set_lane_reg(npu_dev, TX_MODE2_PL, 0, TX_RXCAL);
365
366 return PROCEDURE_COMPLETE;
367 }
368 DEFINE_PROCEDURE(phy_disable_tx_rxcal);
369
phy_rx_dccal(struct npu_dev * npu_dev)370 static uint32_t phy_rx_dccal(struct npu_dev *npu_dev)
371 {
372 if (phy_read(npu_dev, RX_LANE_BUSY_VEC_0_15)
373 & ~phy_read(npu_dev, RX_INIT_DONE_VEC_0_15))
374 return PROCEDURE_INPROGRESS;
375
376 return PROCEDURE_NEXT;
377 }
378
phy_rx_dccal_start(struct npu_dev * npu_dev)379 static uint32_t phy_rx_dccal_start(struct npu_dev *npu_dev)
380 {
381 uint64_t val;
382
383 /* Save EO step control */
384 val = phy_read(npu_dev, RX_EO_STEP_CNTL_PG);
385 npu_dev->procedure_data = val;
386
387 phy_write(npu_dev, RX_EO_STEP_CNTL_PG,
388 RX_EO_ENABLE_LATCH_OFFSET_CAL
389 | RX_EO_ENABLE_CM_COARSE_CAL);
390
391 val = phy_read(npu_dev, RX_RECAL_ABORT_VEC_0_15);
392 val |= phy_lane_mask(npu_dev);
393 phy_write(npu_dev, RX_RECAL_ABORT_VEC_0_15, val);
394
395 val = phy_read(npu_dev, RX_RUN_LANE_VEC_0_15);
396 val |= phy_lane_mask(npu_dev);
397 phy_write(npu_dev, RX_RUN_LANE_VEC_0_15, val);
398
399 return PROCEDURE_NEXT;
400 }
401
phy_rx_dccal_complete(struct npu_dev * npu_dev)402 static uint32_t phy_rx_dccal_complete(struct npu_dev *npu_dev)
403 {
404 /* Poll for completion on relevant lanes */
405 if ((phy_read(npu_dev, RX_INIT_DONE_VEC_0_15) & phy_lane_mask(npu_dev))
406 != phy_lane_mask(npu_dev))
407 return PROCEDURE_INPROGRESS;
408
409 return PROCEDURE_NEXT;
410 }
411
phy_rx_dccal_fifo_init(struct npu_dev * npu_dev)412 static uint32_t phy_rx_dccal_fifo_init(struct npu_dev *npu_dev)
413 {
414 uint64_t val;
415
416 val = phy_read(npu_dev, RX_RUN_LANE_VEC_0_15);
417 val &= ~phy_lane_mask(npu_dev);
418 phy_write(npu_dev, RX_RUN_LANE_VEC_0_15, val);
419
420 /* Turn off recal abort */
421 val = phy_read(npu_dev, RX_RECAL_ABORT_VEC_0_15);
422 val &= ~phy_lane_mask(npu_dev);
423 phy_write(npu_dev, RX_RECAL_ABORT_VEC_0_15, val);
424
425 /* Restore original settings */
426 phy_write(npu_dev, RX_EO_STEP_CNTL_PG, npu_dev->procedure_data);
427
428 /* FIFO Init */
429 set_lane_reg(npu_dev, TX_MODE2_PL, 0, TX_UNLOAD_CLK_DISABLE);
430 set_lane_reg(npu_dev, TX_CNTL_STAT2, TX_FIFO_INIT, TX_FIFO_INIT);
431 set_lane_reg(npu_dev, TX_MODE2_PL, TX_UNLOAD_CLK_DISABLE,
432 TX_UNLOAD_CLK_DISABLE);
433
434 return PROCEDURE_COMPLETE;
435 }
436 DEFINE_PROCEDURE(phy_rx_dccal, phy_rx_dccal_start, phy_rx_dccal_complete,
437 phy_rx_dccal_fifo_init);
438
phy_rx_training(struct npu_dev * npu_dev)439 static uint32_t phy_rx_training(struct npu_dev *npu_dev)
440 {
441 uint16_t val;
442
443 if (!npu_dev->procedure_data) {
444 val = phy_read(npu_dev, RX_RUN_LANE_VEC_0_15);
445 val |= phy_lane_mask(npu_dev);
446 phy_write(npu_dev, RX_RUN_LANE_VEC_0_15, val);
447 }
448
449 npu_dev->procedure_data++;
450 if (npu_dev->procedure_data >= 1000000)
451 return PROCEDURE_COMPLETE | PROCEDURE_FAILED;
452
453 val = phy_read(npu_dev, RX_RUN_LANE_VEC_0_15);
454 if ((val & phy_lane_mask(npu_dev)) != phy_lane_mask(npu_dev))
455 return PROCEDURE_INPROGRESS;
456
457 return PROCEDURE_COMPLETE;
458 }
459 DEFINE_PROCEDURE(phy_rx_training);
460
461 static struct procedure *npu_procedures[] = {
462 &procedure_stop,
463 &procedure_nop,
464 NULL,
465 NULL,
466 &procedure_phy_reset,
467 &procedure_phy_tx_zcal,
468 &procedure_phy_rx_dccal,
469 &procedure_phy_enable_tx_rxcal,
470 &procedure_phy_disable_tx_rxcal,
471 &procedure_phy_rx_training,
472 &procedure_reset_npu_dl,
473
474 /* Place holders for pre-terminate and terminate procedures */
475 &procedure_nop,
476 &procedure_nop};
477
478 /* Run a procedure step(s) and return status */
get_procedure_status(struct npu_dev * dev)479 static uint32_t get_procedure_status(struct npu_dev *dev)
480 {
481 uint32_t result;
482 uint16_t procedure = dev->procedure_number;
483 uint16_t step = dev->procedure_step;
484 const char *name = npu_procedures[procedure]->name;
485
486 do {
487 result = npu_procedures[procedure]->steps[step](dev);
488
489 if (result & PROCEDURE_NEXT) {
490 step++;
491 NPUDEVINF(dev, "Running procedure %s step %d\n", name, step);
492 }
493 } while (result & PROCEDURE_NEXT);
494
495 dev->procedure_step = step;
496
497 if (result & PROCEDURE_COMPLETE)
498 NPUDEVINF(dev, "Procedure %s complete\n", name);
499 else if (mftb() > dev->procedure_tb + msecs_to_tb(100)) {
500 NPUDEVINF(dev, "Procedure %s timed out\n", name);
501 result = PROCEDURE_COMPLETE | PROCEDURE_FAILED;
502 }
503
504 /* Mask off internal state bits */
505 dev->procedure_status = result & PROCEDURE_STATUS_MASK;
506
507 return dev->procedure_status;
508 }
509
npu_dev_procedure_read(struct npu_dev * dev,uint32_t offset,uint32_t size,uint32_t * data)510 static int64_t npu_dev_procedure_read(struct npu_dev *dev, uint32_t offset,
511 uint32_t size, uint32_t *data)
512 {
513 int64_t rc = OPAL_SUCCESS;
514
515 if (size != 4) {
516 /* Short config reads are not supported */
517 prlog(PR_ERR, "NPU%d: Short read of procedure register\n", dev->npu->phb.opal_id);
518 return OPAL_PARAMETER;
519 }
520
521 *data = 0;
522
523 switch (offset) {
524 case 0:
525 /* Only run the procedure if not already complete */
526 if (dev->procedure_status & PROCEDURE_COMPLETE)
527 *data = dev->procedure_status;
528 else
529 *data = get_procedure_status(dev);
530
531 break;
532
533 case 4:
534 *data = dev->procedure_number;
535 break;
536
537 default:
538 prlog(PR_ERR, "NPU%d: Invalid vendor specific offset 0x%08x\n",
539 dev->npu->phb.opal_id, offset);
540 rc = OPAL_PARAMETER;
541 }
542
543 return rc;
544 }
545
npu_dev_procedure_write(struct npu_dev * dev,uint32_t offset,uint32_t size,uint32_t data)546 static int64_t npu_dev_procedure_write(struct npu_dev *dev, uint32_t offset,
547 uint32_t size, uint32_t data)
548 {
549 const char *name;
550 int64_t rc = OPAL_SUCCESS;
551
552 if (size != 4) {
553 /* Short config writes are not supported */
554 prlog(PR_ERR, "NPU%d: Short read of procedure register\n",
555 dev->npu->phb.opal_id);
556 return OPAL_PARAMETER;
557 }
558
559 switch (offset) {
560 case 0:
561 /* We ignore writes to the status register */
562 NPUDEVINF(dev, "Ignoring writes to status register\n");
563 break;
564
565 case 4:
566 if (data >= ARRAY_SIZE(npu_procedures) ||
567 !npu_procedures[data]) {
568 NPUDEVINF(dev, "Unsupported procedure number %d\n", data);
569 dev->procedure_status = PROCEDURE_COMPLETE
570 | PROCEDURE_UNSUPPORTED;
571 break;
572 }
573
574 name = npu_procedures[data]->name;
575 if (dev->procedure_number == data
576 && !(dev->procedure_status & PROCEDURE_COMPLETE))
577 NPUDEVINF(dev, "Restarting procuedure %s\n", name);
578 else
579 NPUDEVINF(dev, "Starting procedure %s\n", name);
580
581 dev->procedure_status = PROCEDURE_INPROGRESS;
582 dev->procedure_number = data;
583 dev->procedure_step = 0;
584 dev->procedure_data = 0;
585 dev->procedure_tb = mftb();
586 break;
587
588 default:
589 NPUDEVINF(dev, "Invalid vendor specific offset 0x%08x\n", offset);
590 rc = OPAL_PARAMETER;
591 }
592
593 return rc;
594 }
595
npu_dev_procedure(void * dev,struct pci_cfg_reg_filter * pcrf,uint32_t offset,uint32_t len,uint32_t * data,bool write)596 int64_t npu_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf,
597 uint32_t offset, uint32_t len, uint32_t *data,
598 bool write)
599 {
600 struct pci_virt_device *pvd = dev;
601 struct npu_dev *ndev = pvd->data;
602
603 if (write)
604 return npu_dev_procedure_write(ndev, offset - pcrf->start,
605 len, *data);
606
607 return npu_dev_procedure_read(ndev, offset - pcrf->start, len, data);
608 }
609
npu_dev_procedure_reset(struct npu_dev * dev)610 void npu_dev_procedure_reset(struct npu_dev *dev)
611 {
612 dev->procedure_status = 0;
613 dev->procedure_number = 0;
614 dev->procedure_step = 0;
615 dev->procedure_data = 0;
616 }
617